[英]Promises and Q - Completing a long series of functions with a forEach
對於如何最好地編寫此內容有些困惑-希望此說明清楚。
我有一個forEach函數,我在其中瀏覽了一些JS對象數據,並對每一項執行一個函數:
found.forEach(function(item) {
processData(item['userID']);
});
在這個processData
函數中,我正在使用MongoDB find()調用。
var processData = function(userIDSelected) {
User.find( {_id: userIDSelected},
{gender: 1, country:1}, function(req, foundUser) {
processUserInfo(foundUser[0]['gender']);
});
}
考慮到每個調用將依次運行processUserInfo
,因此我遇到的問題是如何等待forEach中的所有操作完成。
我已經看過使用Q庫和Q.all,但是那是行不通的。
是否有一個Q函數等待長鏈中的所有事情完成?
謝謝
Q.all
:
返回由包含每個承諾的實現值的數組實現的承諾,或者以與第一個被拒絕的承諾相同的拒絕原因被拒絕的承諾。
或Q.allSettled
:
返回一個由承諾狀態快照數組實現的承諾,但僅在所有原始承諾都已解決(即變為已實現或被拒絕)之后才能實現。
因此,您需要做三件事:
修改processData
以及可能的對MongoDB的調用,以便最終得到processData
返回異步操作的承諾。 (抱歉,我不熟悉MongoDB。Alnitak說 ,對於現代版本,如果您不提供回調,則MongoDB會返回一個promise(很好!)。否則, 此問題及其答案可能有助於返回一個promise。基於回調的API。)
使用map
而不是forEach
來獲取結果承諾的數組。
在承諾數組上使用Q.all
或Q.allSettled
。
如果User.find
沒有指定的回調時,會返回一個承諾,#1看起來是這樣的 :
var processData = function(userIDSelected) {
return User.find(
{_id: userIDSelected},
{gender: 1, country:1}
).then(function(req, foundUser) { // <== Check these args with the MongoDB docs!
return processUserInfo(foundUser[0]['gender']);
});
};
var processData = function(userIDSelected) {
var d = Q.defer();
User.find(
{_id: userIDSelected},
{gender: 1, country:1},
function(req, foundUser) {
processUserInfo(foundUser[0]['gender']);
d.resolve(/*...data could go here...*/); // You'd use d.reject() if there were an error
});
return d.promise;
};
然后是2和3的樣子:
Q.all(found.map(function(item) { // Or Q.allSettled
return processData(item);
}))
.then(...)
.catch(...);
如果processData
僅使用其第一個參數(忽略任何其他參數),則可以放棄中介函數:
Q.all(found.map(processData)) { // Or Q.allSettled
.then(...)
.catch(...);
...但僅當processData
忽略多余的args時,因為map
會將其傳遞給三個(值,其索引和數組)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.