在NodeJS中进行同步MongoJS查询

时间:2015-11-05 15:00:36

标签: javascript node.js mongodb express mongojs

我使用MongoJS驱动程序在我的Nodejs服务器中运行查询。我有两个查询要按顺序运行,但是当我发出请求时,javascript的异步性质会给我带来意想不到的结果。这就是我所拥有的:

app.post('/teams', isLoggedIn, function (req, res){

    db.collection.update({"_id":mongojs.ObjectId(req.body.x)},{$pull:{"teams":{"_id":req.body.y}}},
    function (err, docs) {
    console.log(docs); res.json(docs);
    });

    db.collection.update({"_id":mongojs.ObjectId(req.body.x)},{$push:{"teams":{"_id":req.body.y,"team":req.body.z, "member":true}}},
    function (err, docs) {
    console.log(docs); res.json(docs);
    });

});

我需要按顺序运行这些查询($pull和THEN $push)。我尝试在第一个查询的function(err, docs){...}内运行第二个查询,但即使我通过reqreq的变量版本,它也会返回为未定义。什么是让这些查询按顺序运行的最佳方法?

更新:这是我最终使用基于this tutorial的异步(感谢提示,满意度)。我应该提到的一点是,这个查询存在于一个循环中,我在上面的示例请求中没有包含这个查询。

async.parallel([
       function(callback) { //This is the first task, and callback is its callback task
          console.log('first1 '+x+'pulled');
          db.collection.update({"_id":mongojs.ObjectId(req.body.x)},{$pull:{"teams":{"_id":req.body.y}}}, function(err, docs) {
          //Now we have saved to the DB, so let's tell async that this task is done
          res.json(docs);
          callback();
        });
       },
       function(callback) { //This is the second task, and callback is its callback task
          console.log('second1 '+x+'pushed');
          db.collection.update({"_id":mongojs.ObjectId(req.body.x)},{$push:{"teams":{"_id":req.body.y,"team":req.body.z, "member":true}}}, callback); //Since we don't do anything interesting in db.save()'s callback, we might as well just pass in the task callback 
          }
          ], function(err, docs) { //This is the final callback
          res.json(docs);
          console.log('Both a and b are saved now');
});

更新2:也许我说得太早了。查询仍然没有按预期完成大约5%的时间。

2 个答案:

答案 0 :(得分:2)

正如您自己提到的,NodeJS是异步工作的。

要同步完成工作,您需要使用库,例如​​async或使用promises

快速举例说明如何使用async的“auto”来完成工作(我喜欢使用它,因为我对简单的“瀑布式”方法有更多的控制权):

async.auto({
    pull: function(callback){
        db.collection.update({"_id":mongojs.ObjectId(req.body.x)},{$pull:{"teams":{"_id":req.body.y}}},callback);
    },
    push: ['pull', function(callback, results){
        db.collection.update({"_id":mongojs.ObjectId(req.body.x)},{$push:{"teams":{"_id":req.body.y,"team":req.body.z, "member":true}}},callback);
    }]
}, function(err, results) {
    if(err) {
        console.log(err);
    }
    console.log(results.pull);
    console.log(results.push);
});

我没有对代码进行测试,请随意查看代码here

答案 1 :(得分:1)

var Q = require("q");

app.post('/teams', isLoggedIn, function (req, res){

firstFunction(req,res).then(function(result){
    var resultFromFirst = result
    db.collection.update({"_id":mongojs.ObjectId(req.body.x)},{$push:        {"teams":{"_id":req.body.y,"team":req.body.z, "member":true}}},
        function (err, docs) {
            console.log(docs); res.json(docs);
        });

})


});

var firstFunction = function (req,res) {
console.log("first function")
var d1 = Q.defer();
  db.collection.update({"_id":mongojs.ObjectId(req.body.x)},{$pull:    {"teams":{"_id":req.body.y}}},
    function (err, docs) {
        console.log(docs); res.json(docs);
        d1.resolve(docs);
    });


return d1.promise;
}

运行前:

npm install q -g

如果包安装中有任何问题,请使用sudo

相关问题