我使用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){...}
内运行第二个查询,但即使我通过req
或req
的变量版本,它也会返回为未定义。什么是让这些查询按顺序运行的最佳方法?
更新:这是我最终使用基于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%的时间。
答案 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