【问题标题】: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() 来执行所有查询。我对这一切都很陌生,所以请原谅一些初学者的错误。

【问题讨论】:

    标签: node.js mongodb asynchronous mongoose mean-stack


    【解决方案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)
                });
            });
        });
    

    【讨论】:

    • 感谢您的解释和回答。它完美地工作:)
    猜你喜欢
    • 2017-11-21
    • 2018-11-30
    • 2015-10-28
    • 2016-12-26
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    相关资源
    最近更新 更多