对如何最好地写这个有点困惑 - 希望这个描述是清楚的。
我有一个 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
:
Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected.
或Q.allSettled
:
Returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, i.e. become either fulfilled or rejected.
所以你会做三件事:
修改
processData
以及可能的对 MongoDB 的调用,以便最终processData
返回异步操作的 promise 。 (抱歉,我对 MongoDB 不熟悉。 Alnitak says 在现代版本中,如果您不提供回调,MongoDB 将返回一个 promise (很好!)。否则, this question and its answers may help 返回回调的 promise -基于 API。)使用
map
而不是forEach
来获取结果 Promise 的数组。对该 Promise 数组使用
Q.all
或Q.allSettled
。
如果 User.find
在未指定回调的情况下返回一个 Promise,则 #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']);
});
};
如果没有,您可以使用 Q.defer
自行完成:
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
忽略额外的参数,因为map
将向其传递三个(值、索引和数组)。
关于javascript - Promises 和 Q - 使用 forEach 完成一系列函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35409319/