尝试进行嵌套查询时已调用节点异步回调
Posted
技术标签:
【中文标题】尝试进行嵌套查询时已调用节点异步回调【英文标题】:Node async callback was already called when trying to make a nested query 【发布时间】:2016-10-23 01:27:25 【问题描述】:我在尝试使用 MEAN 堆栈进行异步查询时收到 Callback was already called 错误。我需要第二个回调仅在嵌套查询完成后触发(根据代码中的 cmets)。为什么会出现此错误?
路线示例:
router.route('/teams/:user_id').get(function (req, res)
TeamProfile.find(
Members :
$in : [req.params.user_id]
).exec(function (err, teamProfiles)
var asyncTasks = [];
teamProfiles.forEach(function (teamProfile)
asyncTasks.push(function (callback)
UserProfile.find(
UserID :
$in : teamProfile.Members.map(function (id)
return id;
)
, function (err, userProfiles)
teamProfile.Members = userProfiles;
callback();
)
);
);
teamProfiles.forEach(function (teamProfile)
asyncTasks.push(function (callback)
Draft.find(
_id :
$in : teamProfile.Drafts.map(function (id)
return id;
)
, function (err, drafts)
teamProfile.Drafts = drafts;
drafts.forEach(function (draft)
Comment.find(
_id :
$in : draft.Comments.map(function (id)
return id;
)
).exec(function (err, comments)
draft.Comments = comments;
callback();
//This is where the callback should be called
//Throws Error: Callback was already called.
)
)
)
);
);
async.parallel(asyncTasks, function ()
res.json(teamProfiles)
);
);
)
我正在使用async.parallel()
来执行所有查询。我对这一切都很陌生,所以请原谅一些初学者的错误。
【问题讨论】:
【参考方案1】:您正在同步迭代 drafts
并在第一项上调用 async 的 callback
函数。当您尝试使用第二个项目再次调用它时出现错误是预期的行为。
您应该在完成所有草稿查询后调用 done 回调,而不是每个查询。由于您使用的是异步,您可以嵌套另一个 async.each
来处理此问题:
router.route('/teams/:user_id').get(function (req, res)
TeamProfile.find(
Members :
$in : [req.params.user_id]
).exec(function (err, teamProfiles)
var asyncTasks = [];
teamProfiles.forEach(function (teamProfile)
asyncTasks.push(function (callback)
UserProfile.find(
UserID :
$in : teamProfile.Members.map(function (id)
return id;
)
, function (err, userProfiles)
teamProfile.Members = userProfiles;
callback();
);
);
);
teamProfiles.forEach(function (teamProfile)
asyncTasks.push(function (callback)
Draft.find(
_id :
$in : teamProfile.Drafts.map(function (id)
return id;
)
, function (err, drafts)
teamProfile.Drafts = drafts;
async.each(drafts, function(draft, draftCallback)
Comment.find(
_id :
$in : draft.Comments.map(function (id)
return id;
)
).exec(function (err, comments)
draft.Comments = comments;
draftCallback();
);
, function(err)
callback();
);
);
);
);
async.parallel(asyncTasks, function ()
res.json(teamProfiles)
);
);
);
【讨论】:
感谢您的解释和回答。它完美地工作:)以上是关于尝试进行嵌套查询时已调用节点异步回调的主要内容,如果未能解决你的问题,请参考以下文章
如何处理一对多关系中的嵌套 mongoose 查询和异步问题?