等待解决多个回调
Wait to resolve multiple callbacks
我正在尝试从猫鼬的一次调用中获取 ID。之后,这些 ID 中的每一个都用于进行另一个 returns 多个对象的调用。我正在尝试获取所有这些对象。
我目前的尝试是这样的:
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 但我不确定它究竟是如何工作的。
有谁知道如何让它发挥作用?
谢谢,
丹尼尔
你需要做异步循环,等待最终响应。你可以这样做
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);
});
});
上面的代码可能 运行 因为我没有 运行 但这是你可以实现你想要的东西的方法。
是的,applying promises 听起来是个好主意。
您需要选择 an implementation, on which it will depend how to promisify 您的 find
方法调用。假设您有一个 find
函数,它接受接收器和选项,并且 returns 您是一个承诺 - (编辑)在猫鼬中,您很幸运并且 .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-promises 被解析(并行)的部分。
我正在尝试从猫鼬的一次调用中获取 ID。之后,这些 ID 中的每一个都用于进行另一个 returns 多个对象的调用。我正在尝试获取所有这些对象。
我目前的尝试是这样的:
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 但我不确定它究竟是如何工作的。
有谁知道如何让它发挥作用?
谢谢, 丹尼尔
你需要做异步循环,等待最终响应。你可以这样做
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);
});
});
上面的代码可能 运行 因为我没有 运行 但这是你可以实现你想要的东西的方法。
是的,applying promises 听起来是个好主意。
您需要选择 an implementation, on which it will depend how to promisify 您的 find
方法调用。假设您有一个 find
函数,它接受接收器和选项,并且 returns 您是一个承诺 - (编辑)在猫鼬中,您很幸运并且 .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-promises 被解析(并行)的部分。