2016-01-27 225 views
0

我正在學習nodejs中的承諾,下面是我的示例代碼。 的下面的代碼的輸出是 試驗 - 1個 試驗 - 2 試驗 - 3 測試 - 4nodejs中的循環承諾

var Q = require('q'); 
var promise = Q.when('test'); 

promise.then(function(val) { 
console.log(val + '-' + '1'); 
}); 

promise.then(function(val) { 
console.log(val + '-' + '2'); 
}); 

promise.then(function(val) { 
console.log(val + '-' + '3'); 
}); 

promise.then(function(val) { 
console.log(val + '-' + '4'); 
}); 

我想知道如何可以使用用於循環寫相同的代碼。

+0

你在學習循環,承諾還是兩者?你已經知道JS中的循環和回調了嗎? – Bergi

+0

@Bergi,我嘗試下面的代碼 var Q = require('q'); var promise = Q.when('test'); (var idx = 1; idx <= 4; idx ++){ promise.then(function(val){ console.log(val +' - '+ idx); }); } 但是輸出是測試-5測試-5測試-5測試-5 – refactor

+1

啊是的,這只是[臭名昭着的閉環在循環問題](http://stackoverflow.com/q/1451009/1048572) – Bergi

回答

1

最後,我可以做我想要,下面是代碼

var Q = require('q'); 
var promise = Q.when('test'); 

for(var idx = 1 ; idx <= 4 ; idx++) 
{ 
    (function() 
    { 
     var temp = idx; 
     promise.then(function(val) { 
      console.log(val + '-' + temp); 
      }); 

    })(); 
} 

它的工作原理!我保證:)

0

qdocumentation

如果你想運行的功能,動態構建的序列, 你會想是這樣的:

var funcs = [foo, bar, baz, qux]; 

var result = Q(initialVal); 
funcs.forEach(function (f) { 
    result = result.then(f); 
}); 
return result; 

哪裏initialVal是你Q.when('test')

1

這實際上並非特定於承諾。如果你在迴路中創建回調,you'll need an extra closure scope,除此之外它是相當標準的。

但是,對於您的特定情況,最簡單的方法是僅使用單個回調,因爲它們都附加到相同的承諾,並且會收到相同的值。所以你用

require('q').when('test').then(function(val) { 
    for (var i=1; i<=4; i++) { 
     console.log(val + '-' + i); 
    } 
}); 
-1

首先,因爲有本土ES6承諾,我認爲這是不,除非你有支持舊的瀏覽器或舊版本的NodeJS使用一個庫是個好主意。

當您使用promise時,您正在使用異步代碼,因此,您可以以不同的方式進行循環。

想象一下,你有這樣的片段:

function step1 (item){ 
    return new Promise((resolve, reject) => { 
    setTimeout(()=>{ 
     resolve('step 1 for item ' + item); 
    }, 1000); 
    }); 
} 

function step2 (item){ 
    return new Promise((resolve, reject) => { 
    setTimeout(()=>{ 
     resolve('step 2 for item ' + item); 
    }, 1000); 
    }); 
} 

function step3 (item){ 
    return new Promise((resolve, reject) => { 
    setTimeout(()=>{ 
     resolve('step 3 for item ' + item); 
    }, 1000); 
    }); 
} 

function processItem (item) { 
    return step1(item).then(result =>{ 
    console.log(result); 
    return step2(item); 
    }).then(result =>{ 
    console.log(result); 
    return step3(item); 
    }).then(result =>{ 
    console.log(result); 
    return ('finished process of item ' + item); 
    }).catch(err =>{ 
    throw (err); 
    }); 
} 

其中processItem功能將被應用到項目陣列。

  • A.運行一個foor循環。

上面的代碼是異步的,所以,當你運行它,然後inmediatly執行下一個,所以,如果processItem功能需要3秒完成,並且要將該功能應用於10個項目,這將需要3秒鐘,因爲Promise呼叫將被嚴格執行,但無需等待完成其中的任何一個。

示例代碼:

function promiseFor(set, fn){ 
    return new Promise((resolve, reject) => { 
     return arr.map(item =>()=> fn(item)).forEach(proc => { 
     return proc().then(res => { 
      resolve(); 
     }).catch(err=>{ 
      console.log(err); 
     }); 
     }); 
    }); 
} 
  • B.運行序列中的承諾。 順序沒有開始,直到前一個已經執行到執行任何承諾,這就像一個非異步福爾循環: 例子:
function sequence (set, fn){ 
    return set.map(item =>()=> fn(item)).reduce((curr, next)=> { 
    return curr.then(()=>{ 
     return next(); 
    })},Promise.resolve()); 
}