我正在尝试使用Promise来等待异步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)
console.log(err);
else
console.log(match._id);
});
});
return deferred.promise;
};
在这里使用:
forEachMatch(matches, function() {
console.log("DONE");
res.status(200).json({
bob,
matches: matches,
});
});
我的控制台输出如下:所有match._id
都已打印,但DONE
从未打印过。
有什么想法解决它吗?我从节点和承诺开始,所以我当然忘记了一些东西,但我没有看到。
感谢您的回答。
最终解决方案,感谢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
});
});
答案 0 :(得分:1)
在你的情况下,匹配更好地使用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,
});
});
https://github.com/kriskowal/q/wiki/API-Reference#promiseall
答案 1 :(得分:1)
您正在退回延期承诺,并且该承诺未得到解决或拒绝。请尝试以下方法:
CustomHandler
};
然后调用者将成为
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;
答案 2 :(得分:0)
您从未调用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");
});