【问题标题】:How the Node.js async eachLimit works in this situation?Node.js async eachLimit 在这种情况下如何工作?
【发布时间】: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
});

【问题讨论】:

    标签: node.js mongodb asynchronous callback asynccallback


    【解决方案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没有参数?
    • 有效,对不起,这是我的错误!谢谢!
    • 嘿嘿嘿嘿嘿!介意我在这个问题上请你帮忙吗? stackoverflow.com/questions/16445649/…
    • 所有回调都缺少返回语句。
    猜你喜欢
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 2019-12-04
    • 2018-06-16
    • 2017-06-21
    • 2018-01-19
    • 1970-01-01
    • 2021-12-06
    相关资源
    最近更新 更多