使用node.js异步系列插入错误

时间:2014-09-04 06:59:36

标签: javascript node.js mongodb asynchronous

我有一个在MongoDB中插入文档的for循环。使用异步系列我运行循环五次然后关闭连接。由于某些奇怪的原因,我第六次执行循环时出现插入错误。我只是不确定这里发生了什么。有任何想法吗?

var mycollection= "abcd";
var count = 5;
var db;
var col;

async.series([
 // Connect to DB
 function(callback) {
  MongoClient.connect("mongodb://connection-path-here",function(error, db2) {
      if (error) {console.log("db connect error");callback(error,"db connect error"); return;} 
      db = db2;
      callback(null,"connect success");
  });
},
function(callback) {
  col = db.collection(mycollection);
  callback(null,"collection success");
},
function(callback) {
  console.log ("insert begin ...");               
  for (var i = 1; i <= count; i++) {
    console.log("inserting ....." + i);
    col.insert({c:i}, function(error,result) {
        if (error) {console.log("insert error:" + i);callback(error,"insert error"); return;}
    });
  }
callback(null,"insert success");
},
function (callback){
  console.log ("close db");db.close();
  callback(null,"connection closed");
}
], function(error, results) {
    if (error) { console.log("error"); }
        console.log(results);
});

输出

insert begin ...
inserting .....1
inserting .....2
inserting .....3
inserting .....4
inserting .....5
close db
insert error:6
error
  [ 'connect success', 'collection success', 'insert error' ]
insert error:6
insert error:6
insert error:6
insert error:6

2 个答案:

答案 0 :(得分:1)

你开始很好但是你在这里混合了异步和非异步方法:

function(callback) {
  console.log ("insert begin ...");               
  for (var i = 1; i <= count; i++) {
    console.log("inserting ....." + i);
    col.insert({c:i}, function(error,result) {
        if (error) {console.log("insert error:" + i);callback(error,"insert error"); return;}
    });
  }
callback(null,"insert success");
},

这不会等待插入在迭代下一个循环之前完成,所以你需要等待的东西。尝试&#34; async.whilst&#34;:

function(callback) {
    var i = 1;
    async.whilst(
        function() { return i <= count },
        function(callback) {
            col.insert({ c: i },function(error,result) {
                if (error)
                    console.log("insert error:" + i);
                i++;
                callback(error);
            });
        },
        function(error) {
          callback(error,"insert sucess")
        }
    );
},

其余的可以按照您的操作进行,结果将发送到系列执行结束。

答案 1 :(得分:0)

所有异步操作都应该是您正在执行的“operations”数组中的函数。你的for循环调用col.insert()6次,但是在第6次操作完成之前你正在调用callback(null,“insert success”) - 这将导致竞争条件,所以有时它可能实际上使它完全通过或者可能它只会插入几个记录,具体取决于每个插入的时间。

请参阅下面修改后的代码来解决问题:

var mycollection= "abcd";
var count = 5;
var db;
var col;

// create operations array with first two operations
var operations = [
  // Connect to DB
   function(callback) {
    MongoClient.connect("mongodb://connection-path-here",function(error, db2) {
        if (error) {console.log("db connect error");callback(error,"db connect error"); return;} 
        db = db2;
        callback(null,"connect success");
    });
  },
  function(callback) {
    col = db.collection(mycollection);
    callback(null,"collection success");
  }
];


// push each insert into operations as its own individual operation
for (var i = 1; i <= count; i++) {
  operations.push(function(callback){
    console.log("inserting ....." + i);
    col.insert({c:i}, function(error,result) {
        if (error) {console.log("insert error:" + i);callback(error,"insert error"); return;}
        // no errors here, so this insert was successful!
        callback(null);
    });
  })
}

// finish pushing the last two operations
operations.push(function(callback) {
  callback(null,"insert success");
});

operations.push(function (callback){
  console.log ("close db");db.close();
  callback(null,"connection closed");
});

// execute all the operations
async.series(operations, function(error, results) {
  if (error) { console.log("error"); }
  console.log(results);
});