Node.js async eachLimit 在这种情况下如何工作?

Posted

技术标签:

【中文标题】Node.js async eachLimit 在这种情况下如何工作?【英文标题】:How the Node.js async eachLimit works in this situation? 【发布时间】:2013-05-02 16:29:47 【问题描述】:

我写了一个小async 脚本,将大量 JSON 文件批量插入到 MongoDB 分片集群中。这是我第一次使用这个模块(我还在学习 Node.js)。我不知道我做得对不对。

代码是瀑布的最后一部分(1):前面的函数结束 使用具有dbcollfiles 属性的对象。 files 数组包含数百个文件路径和函数 apply 到数组的每个元素同样是一个瀑布 (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
);

【问题讨论】:

【参考方案1】:

如果您不希望它在发生错误时中断,您应该只使用虚假的第一个参数调用回调,就像这样(注意 // 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
);

【讨论】:

看起来合法,但它不起作用。回调 4 被执行,并且脚本在第一个错误发生时立即退出。我错过了什么吗? 所以你调用complete没有参数? 有效,对不起,这是我的错误!谢谢! 嘿嘿嘿嘿嘿!介意我在这个问题上请你帮忙吗? ***.com/questions/16445649/… 所有回调都缺少返回语句。

以上是关于Node.js async eachLimit 在这种情况下如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 最佳实践异常处理——在 Async/Await 之后

Node.js 中 For 循环中的 async.waterfall

Node.js 中 For 循环中的 async.waterfall

Node.js - 使用 'async' 和 'await' 和 sequelize ORM

转学习使用 Node.js 中 async-hooks 模块

node.js 中的 async.eachSeries