Node.js async.series()不等待回调完成

时间:2014-11-19 13:30:20

标签: javascript node.js mongodb async.js

我的代码在从未调用mongoose.disconnect()并且节点程序有时间执行所有回调时有效。在程序结束时调用mongoose.disconnect()并且连接丢失时,mongo的插入自然不会发生。

此异步不等待这些插入完成。为什么,我该如何解决?

mObjectList =准备插入的对象数组

insertMongoObj: function(mObjectList, callback) {
  var tasks = [];

  for (i in mObjectList) {
    tasks.push(mObjectList[i].save());
  }

  async.parallel(tasks, function(err) {
    if (err) {
      callback(err, 0);
    }
  });
  callback(null, tasks.length);
}

感谢您的快速回复!改变了功能,但同样的事情。连接从未关闭且程序永远不会退出时工作。 Mongoose.disconnect()在这些插入之前仍然关闭连接。

insertMongoObj : function(mObjectList, callback){

    var tasks = [];

    for (i in mObjectList) {
      tasks.push(mObjectList[i].save.bind(mObjectList[i]));
    }

    async.parallel(tasks, function(err) {
        if(err) return callback(err);
        winston.info("  file processing ready");
    });

    return callback();
}

之前的函数调用在这里:

mongoose.connection.once('open', function () {
    talendToMongo.processTalendExport(objPaths, function(){
        mongoose.disconnect();
    });

});

processTalendExport : function(talendEntityLocationList, callback){
    var mongoObjectList = [];
    var self = this;
    for(obj in talendEntityLocationList){
        winston.info("**Start processing directory:" + talendEntityLocationList[obj]);
        var fileList = fs.readdirSync(talendEntityLocationList[obj]);
        this.processEntityDir(talendEntityLocationList[obj], fileList, function(mongoObjectList){
            self.insertMongoObj(mongoObjectList, function(err){
                if(err) {
                    winston.error("  Error processing file:" + talendEntityLocationList[obj]);
                        process.exit(0);
                    } else {
                        winston.info(" Mongo Objects inserted");
                    }
                });
            });
        }
        callback();
    }

insertMongoObj : function(mObjectList, callback){
    var tasks = [];

    for (i in mObjectList) {
        tasks.push(mObjectList[i].save.bind(mObjectList[i]));
    }

    async.parallel(tasks, function(err) {
        if(err) return callback(err);
          winston.info("  file processing ready");
        });

        return callback();
    }

3 个答案:

答案 0 :(得分:1)

您需要将最后一个回调调用移动到async.parallel的回调:

for (i in mObjectList) {
  tasks.push(mObjectList[i].save.bind(mObjectList[i]));
}

async.parallel(tasks, function(err) {
     if (err) {
         return callback(err, 0);
     }
     return callback(null, tasks.length);
 });

答案 1 :(得分:0)

这是async.each理想的绝佳案例。

insertMongoObj: function(mObjectList, callback) {
    async.each(mObjectList, function(obj, done){
        obj.save(done);
    }, callback);
}

更新

processTalendExport中,您在callback()循环之后for(obj in talendEntityLocationList){而不是在插入完成之后,因此在插入有时间完成之前它会调用.disconnect 。取决于客户端和网络,这可能总是导致故障,或者有时仅失败。您应该使用async.each(talendEntityLocationList, ...来查看该列表。

答案 2 :(得分:0)

最后让这个工作纠正了以前的函数回调并修复了async.eachSeries回调:

    insertMongoObjects : function(mongoObjList, callback){
        var insertCnt = 0;
        winston.info("    Start mongo object insert");
        async.eachSeries(mongoObjList,
            function(mongoObj, done){
                    mongoObj.save(function(save_result){
                        if(!save_result){ 
                            insertCnt++
                            done(null);
                        } else { done(save_result); }
                    });
            },
            function(err){
                if(err) {
                    winston.error("    Error inserting mongo object:");
                    winston.error(err);
                    callback(err);
                } else {
                    winston.info("    Mongo object insert successful for:" + insertCnt);
                    callback();
                }
            }
        );
    }