等待解决多个回调
Posted
技术标签:
【中文标题】等待解决多个回调【英文标题】:Wait to resolve multiple callbacks 【发布时间】:2015-05-30 04:06:54 【问题描述】:我正在尝试从与猫鼬的一次通话中获取 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 的所有回调。我看过使用 Promise,但我不确定它是如何工作的。
有谁知道如何让它工作?
谢谢你, 丹尼尔
【问题讨论】:
【参考方案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);
);
);
上面的代码可能无法运行,因为我没有运行它,但这是你可以实现你想要的。
【讨论】:
谢谢,我会试试这个。这是解决这类问题的推荐方法吗? @DVassilev 我并不是说这是一种推荐的方式,而是一种创建异步循环的方式。 我建议进行修改以修复您的代码。谢谢。【参考方案2】:是的,applying promises 听起来是个好主意。
您需要选择an implementation,它将取决于how to promisify 您的find
方法调用。假设您有一个 find
函数,它接受接收者和选项并向您返回一个承诺 - 在猫鼬中(编辑),您很幸运,.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);
);
这里,Promise.all
是它等待直到解决多个 time-find-promise 的部分(并行)。
【讨论】:
感谢@DVassilev 提供find
功能,尽管评论比建议编辑要好(对大多数评论者来说,它确实改变了很多)。
没问题,很抱歉。您的代码也有一个小错误,所以我建议使用更正的版本进行编辑。谢谢你。 @Bergi以上是关于等待解决多个回调的主要内容,如果未能解决你的问题,请参考以下文章