下一篇文章我的鬥爭充分掌握的諾言......簡單的承諾隊列:q.all解決之前推遲承諾解決
我想創建一個簡單的承諾隊列(與節流查詢的長期目標在數據庫上),然後我可以使用Q.all()和Array.protoype.map()。
(這似乎涉及到this question,但我沒有看到有一個明確的決議。)
這裏是我的簡單的框架:
var Q = require('q');
var queue = [];
var counter = 0;
var throttle = 2; // i can do things at most two at a time
var addToQueue = function(data) {
var deferred = Q.defer();
queue.push({data: data, promise: deferred});
processQueue();
return(deferred.promise);
}
var processQueue = function() {
if(queue.length > 0 && counter < throttle) {
counter++;
var item = queue.shift();
setTimeout(function() { // simulate long running async process
console.log("Processed data item:" + item.data);
item.promise.resolve();
counter--;
if(queue.length > 0 && counter < throttle) {
processQueue(); // on to next item in queue
}
}, 1000);
}
}
data = [1,2,3,4,5];
Q.all(data.map(addToQueue))
.then(console.log("Why did get here before promises all fulfilled?"))
.done(function() {
console.log("Now we are really done with all the promises.");
});
但是,正如前文所提到的「再「立即被調用,並且只有」完成「被推遲,直到解決所有的承諾。我注意到在api documentation中,唯一的例子確實使用.done()和not then()。所以也許這是預期的行爲?問題是,那麼我不能連鎖其他行動。在這種情況下,我需要創建另一個延期的承諾,解決它在Q.all的實現功能如下
data = [1,2,3,4,5];
var deferred = Q.defer();
deferred.promise
.then(function() {
console.log("All data processed and chained function called.");
}) // could chain additional actions here as needed.
Q.all(data.map(addToQueue))
.done(function() {
console.log("Now we are really done with all the promises.");
deferred.resolve();
});
到,根據要求的作品,但額外的步驟,讓我覺得我必須失去了一些有關如何正確使用Q.all()。
Q.all()的使用是否有問題,或者上面的額外步驟實際上是正確的方式嗎?
編輯:
Tyrsius指出我的論點來。那麼是不是一個函數的引用,但緊接着的評價功能(執行console.log(...))。下面是我應該怎麼做的:
Q.all(data.map(addToQueue))
.then(function() { console.log("Ahhh...deferred execution as expected.")})
AARGH方式。連續燃燒兩次,立即評估!謝謝你指出。 – Eric
@Eric看到我的編輯速記,可以爲您節省一些麻煩 – Tyrsius
您也可以編寫'.then(console.log.bind(console,'message'))''。 –