【问题标题】:Sequential execution of nodejs code with mongodb query使用mongodb查询顺序执行nodejs代码
【发布时间】:2015-06-15 23:28:27
【问题描述】:

我遇到需要从 nodejs(expressjs) 代码触发 mongodb 查询并将查询结果作为对我的 web api 请求的响应传递的情况,但在我的查询执行下一行代码之前执行并返回空白响应。我写的代码如下,

router.get('/recent', function (req, res){
    var result = [];
    router.db.collection('Posts').find({},{ _id : 1, uid : 1, imagePath : 1, cntLikes : 1, uploadDate : 1}).limit(5).sort({ uploadDate : -1 }).toArray(function(err, docs) {
                docs.forEach( function (doc){
                        router.db.collection('Users').findOne({ "_id" : mongodb.ObjectId(doc.uid)}, function (err, user){
                            doc.username = user;
                            result.push(doc);
                            });
                });


    res.send(result);     // this line send empty result to caller
    });
});

我尝试了回调方法 async.waterfall 并以编程方式停止执行,但一切都失败了。我也尝试过承诺,但我认为承诺在这种情况下对我没有帮助。

【问题讨论】:

    标签: node.js mongodb asynchronous callback


    【解决方案1】:

    您正在循环中使用另一个异步调用,该调用在res.send(result) 之后执行。我认为你所追求的是async.map,所以在你的帖子回调中可能会有类似的东西

    function addUserToPost(item, callback) {
        router.db.collection('Users').findOne({ "_id" : mongodb.ObjectId(doc.uid)}, function (err, user){
            doc.username = user;
            callback(err, doc);
        });
    }
    
    async.map(docs, addUserToPost, function(err, posts) {
        res.send(posts);
    });
    

    您希望将您的“帖子”映射到添加了用户信息的帖子。

    【讨论】:

    • 虽然@subburaj 的回答更干净IMO
    【解决方案2】:

    试试这个:

    router.get('/recent', function (req, res){
        var result = [];
        router.db.collection('Posts').find({},{ _id : 1, uid : 1, imagePath : 1, cntLikes : 1, uploadDate : 1}).limit(5).sort({ uploadDate : -1 }).toArray(function(err, docs) {
        var counter = 0;
                    docs.forEach( function (doc, index){
                            counter++;
                            router.db.collection('Users').findOne({ "_id" : mongodb.ObjectId(doc.uid)}, function (err, user){
                                doc.username = user;
                                result.push(doc);
                                if(counter === index){
                                 res.send(result);    
                                }
                                });
                    });        
        });
    });
    

    【讨论】:

    • 感谢您的解决方案@Subburaj 它有效,但我发现如果检索最后一条记录的查询在任何其他查询之前执行,或者如果任何其他查询比上一个查询需要更多时间来完成,那么结果不会包含该记录(更耗时的查询记录),所以我不得不错过该记录,所以你能告诉我如何解决这种情况。
    猜你喜欢
    • 1970-01-01
    • 2014-03-05
    • 2018-07-19
    • 2017-09-05
    • 2018-10-02
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多