2013-05-08 93 views
4

我写了一些async脚本来批量插入大量的JSON文件到MongoDB分片集群中。这是我第一次使用这个模块(并且我仍然在学习Node.js)。我不知道我是否做得对。Node.js async eachLimit如何在这种情况下工作?

  • 该代码是一个瀑布的最后部分(1):前一函数结束 了与dbcollfiles属性的对象。
  • files数组包含了数百个文件路径,并且函数 适用于数组的每个元素,也是瀑布(2)。
  • 瀑布(2)由以下内容组成:读取,解析,插入。当这个瀑布结束时(3)我呼叫complete来完成数组中单个项目的处理,并传递错误(如果有的话)。

到目前为止好,正确吗?

我不明白的是async.eachLimit回调(4)内发生了什么。从文档:

在所有迭代器函数完成 之后调用的回调或发生错误。

也就是说,当所有功能都完成后,next()调用(5)结束脚本。但是,根据文档,当发生单个错误时调用相同的回调(4)。这是我的脚本在发生单个文件失败时停止。

我该如何避免这种情况?

async.waterfall([ // 1 
    // ... 
    function (obj, next) { 
     async.eachLimit(obj.files, 1000, 
      function (file, complete) { 
       async.waterfall([ // 2 
        function (next) { 
         fs.readFile(file, {}, function (err, data) { 
          next(err, data); 
         }); 
        }, 
        function (data, next) { // Parse (assuming all well formed) 
         next(null, JSON.parse(data)); 
        }, 
        function (doc, next) { // Insert 
         obj.coll.insert(doc, {w: 1}, function (err, doc) { 
          next(err); 
         }); 
        } 
       ], function (err, result) { // 3 
        complete(err); 
       }); 
      }, 
      function (err) { // 4 
       if (err) console.error(err); 
       next(null, obj); // 5 
      } 
     ); 
    } 
], function (err, obj) { // Waterfall end 
    if (err) console.error(err); 
    obj.db.close(); // Always close the connection 
}); 

回答

2

如果你不希望它在错误的情况下打破你应该只调用回调与falsy第一个参数,像这样(后// 3看)。 这可以吗?我理解正确吗?

async.waterfall([ // 1 
    // ... 
    function (obj, next) { 
     async.eachLimit(obj.files, 1000, 
      function (file, complete) { 
       async.waterfall([ // 2 
        function (next) { 
         fs.readFile(file, {}, function (err, data) { 
          next(err, data); 
         }); 
        }, 
        function (data, next) { // Parse (assuming all well formed) 
         next(null, JSON.parse(data)); 
        }, 
        function (doc, next) { // Insert 
         obj.coll.insert(doc, {w: 1}, function (err, doc) { 
          next(err); 
         }); 
        } 
       ], function (err, result) { // 3 
        if (err) { 
         console.log(file + ' threw an error'); 
         console.log(err); 
         console.log('proceeding with execution'); 
        } 
        complete(); 
       }); 
      }, 
      function (err) { // 4 
       next(null, obj); // 5 
      } 
     ); 
    } 
], function (err, obj) { // Waterfall end 
    if (err) console.error(err); 
    obj.db.close(); // Always close the connection 
}); 
+0

看起来合法,但它不起作用。执行回调4,脚本在第一个错误发生时立即退出。我错过了什么吗? – gremo 2013-05-08 12:58:26

+0

所以你没有参数调用'complete'? – 2013-05-08 13:25:15

+0

作品,对不起,这是我的错误!谢谢! – gremo 2013-05-08 16:24:25

相关问题