我尝试使用mongoose从一次调用中获取ID。之后,每个ID都用于进行另一个返回多个对象的调用。我正在尝试获取所有这些对象。
我目前的尝试看起来像这样:
var members;
var memberTimes = [];
// Use the Group model to find a specific group
Group.find({
members: {
$elemMatch: {
$eq: req.user._id
}
},
_id: req.params.group_id
}, function(err, group) {
if (err) {
res.send(err);
} else if (!group) {
//res.send(new Error("User not in group or it does not exist"));
}
members = group[0].members;
for (var member of members) {
// Use the Time model to find a specific time
Time.find({
user_id: member
}, function(err, times) {
if (err) {
res.send(err);
}
for (var time of times) {
memberTimes.push(time);
}
});
}
//on completion of all above code, execute res.json(memberTimes);
});
然而,这不起作用,因为我不等待Time#find的所有回调。我已经看过使用promises,但我不确定它是如何使它工作的。
有谁知道如何才能使其发挥作用?
谢谢你, 丹尼尔
答案 0 :(得分:1)
您需要进行异步循环并等待最终响应。你可以做点什么
var members;
function getTimes(mTimes, times, i, done) {
console.log("time " + i);
if (i < times.length) {
console.log(times[i]);
mTimes.push(times[i]);
getTimes(mTimes, times, i + 1, done);
} else {
done(mTimes);
}
}
function asyncLoop(memberTimes, members, i, callback) {
if (i < members.length) {
Time.find({
user_id: members[i]
}, function(err, times) {
if (err) {
res.send(err);
}
console.log(times);
getTimes(memberTimes, times, 0, function(result) {
asyncLoop(memberTimes, members, i + 1, callback);
});
});
} else {
callback(memberTimes);
}
}
// Use the Group model to find a specific group
Group.find({
members: {
$elemMatch: {
$eq: req.user._id
}
},
_id: req.params.group_id
}, function(err, group) {
if (err) {
res.send(err);
} else if (!group) {
//res.send(new Error("User not in group or it does not exist"));
}
members = group[0].members;
var memberTimes = [];
asyncLoop(memberTimes, members, 0, function(memberTimes) {
res.json(memberTimes);
});
});
上面的代码可能无法运行,因为我没有运行它,但这就是你如何实现你想要的。
答案 1 :(得分:1)
是的,applying promises听起来不错。
您需要选择an implementation,how to promisify您的find
方法调用依赖Promise.all
。假设你有一个find
函数接受接收器和选项并返回一个承诺 - (编辑)在mongoose中,你很幸运,.exec()
似乎已经产生了一个承诺:
function find(model, options) {
return model.find(options).exec();
}
然后您的代码将如下所示:
find(Group, {
members: {$elemMatch: {$eq: req.user._id}},
_id: req.params.group_id
}).then(function(group) {
if (!group)
throw new Error("User not in group or it does not exist");
return Promise.all(group[0].members.map(function(member) {
return find(Time, {user_id: member});
}));
}).then(function(memberTimes) {
res.json(memberTimes);
}, function(err) {
res.send(err);
});
在这里,{{3}}是等待多个time-find-promises(并行)解决的部分。