我使用MongoDB在Node.js中编写了我的第一个应用程序,我遇到了根据IF / ELSE条件我需要有2个db.collection.update
语句的情况。
我试图在resJSON
JS对象中返回操作详细信息,但似乎在db.collection.update
语句完成之前回调正在执行,并且默认值resJSON
正在回复每个时间。
详细代码:
var url = require('url');
var fs = require('fs');
var async = require('async');
var passwordGen = require('../../lib/passwordGen');
var http = require("http");
var server = http.createServer();
server.on('request', request);
server.listen(8080,'127.0.0.1');
function request(request, response) {
var userData = '';
request.on('data', function(data)
{
userData += data;
});
request.on('end', function()
{
async.auto({
allProcess: function(callback){
var resJSON = {'inserted':0,'disabled':0,'error':''};
var jsonData = JSON.parse(userData);
if(jsonData.length > 0){
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost:27017/test_db", function(err,db){
if(err) { return console.dir(err); }
var collection = db.collection('users');
var arrDisableRec = [];
for(i=0;i<jsonData.length;i++){
var action = jsonData[i]['action'].toLowerCase();
if(action == 'disable'){
arrDisableRec.push(jsonData[i]['email']);
}else{
var date = new Date();
var obj = {
'createdISO':date,
'created':date,
'updated':date,
'updatedISO':date,
'email':jsonData[i]['email'],
'firstName':jsonData[i]['firstname'],
'lastName':jsonData[i]['lastname'],
'password':passwordGen.getPassword(),
'enabled':true,
'active':true,
'downloaded':true,
'defaultServings':2,
'name':''
};
collection.update(
{'email':jsonData[i]['email']},
{$setOnInsert:obj},
{upsert: true},
function(err,numberAffected,rawResponse) {
if(typeof numberAffected.result.upserted != 'undefined'){
resJSON['inserted'] = resJSON['inserted'] + numberAffected.result.upserted.length;
}
if(typeof numberAffected.result.nModified != 'undefined'){
resJSON['disabled'] = resJSON['disabled'] + parseInt(numberAffected.result.nModified);
}
if(typeof numberAffected.result.writeError != 'undefined'){
resJSON['error'] ='Error Code:'+(numberAffected.result.writeError.code)+', '+numberAffected.result.writeError.errmsg;
}
console.log(resJSON); //shows correct values
}
);
}
if(arrDisableRec.length > 0){
collection.update(
{'email':{$in:arrDisableRec}},
{$set:{'enabled':false}},
{multi:true},
function(err,numberAffected,rawResponse) {
if(typeof numberAffected.result.upserted != 'undefined'){
resJSON['inserted'] = resJSON['inserted'] + numberAffected.result.upserted.length;
}
if(typeof numberAffected.result.nModified != 'undefined'){
resJSON['disabled'] = resJSON['disabled'] + parseInt(numberAffected.result.nModified);
}
if(typeof numberAffected.result.writeError != 'undefined'){
resJSON['error'] ='Error Code:'+(numberAffected.result.writeError.code)+', '+numberAffected.result.writeError.errmsg;
}
console.log(resJSON); //shows correct values
}
);
}
}
});
}
callback(resJSON);
}
},function(resJSON){
response.writeHead(200,{
'Content-Type': 'text/json'
});
response.end(JSON.stringify(resJSON)); //replies back with default resJSON only.
});
});
}
有任何建议/指示吗?
谢谢
答案 0 :(得分:0)
你必须在回调链的末尾调用回调。
例如
console.log(resJSON); //shows correct values
callback(null, resJSON);
您必须确保每个回调链端点都会调用回调。要处理for循环,你必须有一个机制来连接for循环内完成的所有异步调用的所有端点。
例如
if(err) {
return callback(err);
}
请注意,我使用了function callback(err, res)
标准节点原型而不是function callback(res)
更好的是,使用像async
这样的异步流程库或像bluebird
这样的承诺库
答案 1 :(得分:0)
这是针对您的问题的反制解决方案。它现在应该解决你的情况。尝试阅读异步库。这对以后会非常有用。
var counter = 0;
function commoncallback(err,numberAffected,rawResponse) {
if(typeof numberAffected.result.upserted != 'undefined'){
resJSON['inserted'] = resJSON['inserted'] + numberAffected.result.upserted.length;
}
if(typeof numberAffected.result.nModified != 'undefined'){
resJSON['disabled'] = resJSON['disabled'] + parseInt(numberAffected.result.nModified);
}
if(typeof numberAffected.result.writeError != 'undefined'){
resJSON['error'] ='Error Code:'+(numberAffected.result.writeError.code)+', '+numberAffected.result.writeError.errmsg;
}
console.log(resJSON); //shows correct values
counter --;
if(counter == 0) callback(resJSON); //call your main call back here
}
for (i=0; i<jsonData.length; i++) {
if(firstCase) {
counter ++;
collection.update({'email':{$in:arrDisableRec}},
{$set:{'enabled':false}},
{multi:true},commoncallback);
} else {
//another update action
counter++;
}
}