Javascript 用forEach简单承诺
我尝试使用承诺等待异步forEach:Javascript 用forEach简单承诺,javascript,node.js,mongoose,promise,q,Javascript,Node.js,Mongoose,Promise,Q,我尝试使用承诺等待异步forEach: var forEachMatch = function(matches) { var deferred = Q.defer(); matches.forEach(function(match) { var messages = Message.find({'matchid': match._id}, function(err,messages) { if(err) co
var forEachMatch = function(matches) {
var deferred = Q.defer();
matches.forEach(function(match) {
var messages = Message.find({'matchid': match._id}, function(err,messages) {
if(err)
console.log(err);
else
console.log(match._id);
});
});
return deferred.promise;
};
此处使用:
forEachMatch(matches, function() {
console.log("DONE");
res.status(200).json({
bob,
matches: matches,
});
});
我的控制台输出如下:所有匹配。_id
已打印,但已完成
从未打印
有什么好办法吗?我从节点和承诺开始,所以我肯定忘记了一些事情,但我看不到什么
谢谢你的回答
编辑
最终的解决方案,多亏了Alexander Mac:
var forEachMatch = function(matches) {
var promises = matches.map(match => {
return Message
.find({'matchid': match._id})
.populate({
path: 'fromUser toUser',
select: 'id firstname'
})
.then(messages => [match, messages])
.catch(err => {
console.log("Error in forEachMatch");
return [match, null];
});
});
return Q.all(promises);
}
forEachMatch(matches)
.then(messagesByMatch => {
res.status(200).json({
user,
messagesByMatch: messagesByMatch
});
});
您从未调用过
promise.reject
或promise.reject
方法。此外,还为异步操作做出了承诺,而forEach没有
下面是一个脏补丁:
var forEachMatch = function(matches) {
var deferred = Q.defer();
// make the foreach asynchronous
setTimeout(function() {
matches.forEach(function(match) {
// do stuff
});
// notify end
deferred.resolve();
}, 0);
return deferred.promise;
};
// use .then
forEachMatch(matches).then(function() {
console.log("DONE");
});
在您的情况下,最好使用
Q.all
,它接受承诺或值的数组:
var forEachMatch = function(matches) {
var promises = matches.map(match => {
return Message
.find({'matchid': match._id})
.then(messages => [match, messages]);
});
return Q.all(promises);
}
forEachMatch(matches)
.then(results => {
console.log("DONE", results);
res.status(200).json({
bob,
matches: matches,
});
});
您返回的是延期承诺,该承诺不会得到解决或拒绝。请尝试以下操作:
var forEachMatch = function(matches) {
var deferred = Q.defer();
matches.forEach(function(match) {
var messages = Message.find({'matchid': match._id}, function(err,messages) {
if(err)
deferred.reject(err);
else
deferred.resolve(match._id);
});
});
return deferred.promise;
})
然后,调用方将成为
forEachMatch(matches).then(id=>{
console.log("done succesffuly found");
}).catch(err=>{
console.log("not found error",err);
}).done(()=>{
console.log("done")
});
forEachMatch方法只接受一个参数,因此永远不会调用带有DONE的回调。在执行其他操作(如发送请求结果)之前,等待my forEach结束的最佳方式是什么?使用此解决方案是否可以在.map函数结束时返回数据?我在
matches.map的每次迭代中处理一个变量,并希望在最后返回它。是的,这是可能的,但您希望返回什么?所有match.\u id
?请查看我对您答案的编辑,我想处理错误并返回结果。请将其添加为注释。var forEachMatch=function(matches){var result=[];var promises=matches.map(match=>Message.find({'matchid':match.\u id},function(error,messages){if(error)//返回error else){result.push([match,messages]);});return Q.all(promissions);}
那么
和之间有什么区别呢?完成了
闭包?是。然后在每次匹配的迭代中调用
闭包。forEach
?