【问题标题】:NodeJS: How to use async.js to process a list of items in databaseNodeJS:如何使用 async.js 处理数据库中的项目列表
【发布时间】:2016-05-25 11:32:09
【问题描述】:

我遇到了这个问题:我从 API 获得了一个项目列表,我必须将它们保存在数据库中。对于他们每个人,我都必须显示一些反馈,例如“-项目名称。保存在数据库中..”,保存后显示“成功!下一步...”。

我正在使用异步链接来遍历数组中的项目并保存在数据库中。问题是消息不同步。它显示了一堆项目名称消息和一堆成功消息。我的代码如下。

var saveInDB = function saveInDB(item, callback) {

    console.log(' - ' + item.market_name + ' .......');

    // Simulating some delay
    setTimeout(function () {
        console.log('Success! Next....');
        callback(null);
    }, 3000);
}


util.getJsonFromUrl(API_URL, function (err, data) {

    if (err || !data || !data.results || data.results.length == 0)
    {
        console.log('BAD');
    }
    else
    {
        console.log('Items downloaded...');

        async.each(
            data.results,
            function (item, callback) {

                saveInDB(item, callback);

            },
            function (err) {
                if (err) {
                    console.log('ERROR');
                }
                else {
                    console.log('Success!');
                }
            }
        );
    }
});

是的,我曾尝试使用 .series,但我无法让它工作。我一直在寻找示例,但我仍然不知道如何像在 .each 中那样简单地传递项目。

你能帮帮我吗?提前感谢您的帮助。

【问题讨论】:

  • 你试过使用 async.eachSeries 吗?
  • @MedetTleukabiluly 好点,他必须使用 async.eachSeries 因为 async.each 将函数并行应用于每个项目并保证没有顺序。

标签: javascript node.js asynchronous async.js


【解决方案1】:
    async.each(data.results, function (result, cb_results) {
       //try your here 
       cb_results();
    }, function (err) {
        if (err) { throw err; }

    });

示例:

    var returnData = [];
    async.each(data.results, function (result, cb_results) {
       var myJson = {};
       myJson.id = result.id;
       ................
       returnData.push(myJson);
       cb_results();
    }, function (err) {
        if (err) { throw err; }
        callback(returnData);
    });

【讨论】:

    【解决方案2】:

    基于异步documentation 使用async.each

    将函数 iteratee 并行应用于 arr 中的每个项目。

    看起来他们甚至警告说,这不会保留顺序,因为它是平行的:

    请注意,由于此函数将 iteratee 应用于 并行,不能保证迭代函数会 按顺序完成。

    如果我理解正确,您希望您的项目(假设您有 A、B、C)按以下顺序执行:

    //This uses async.eachSeries
    For each - A
    SaveInDB called.
    Timeout set. Waiting to timeout ...
    Processing DB transaction for > A ....... Done.
    Success! Next....
    For each - B
    SaveInDB called.
    Timeout set. Waiting to timeout ...
    Processing DB transaction for > B ....... Done.
    Success! Next....
    For each - C
    SaveInDB called.
    Timeout set. Waiting to timeout ...
    Processing DB transaction for > C ....... Done.
    Success! Next....
    

    而不是按以下顺序(或者可能不同,它的平行,不保证顺序):

    //uses async.each 
    For each - A
    SaveInDB called.
    Timeout set. Waiting to timeout ...
    For each - B
    SaveInDB called.
    Timeout set. Waiting to timeout ...
    For each - C
    SaveInDB called.
    Timeout set. Waiting to timeout ...
    Processing DB transaction for > A ....... Done.
    Success! Next....
    Processing DB transaction for > B ....... Done.
    Success! Next....
    Processing DB transaction for > C ....... Done.
    Success! Next....
    

    因此,将您的方法从async.each 更改为async.eachSeries,并确保您不会混淆,请参阅下面的saveInDB 函数。

    function saveInDB(item, callback) {
       //this will not wait for timeout. 
       console.log('SaveInDB called.');
    
       // Simulating some delay
       setTimeout(function () {
         //everything in this block waits for timeout. 
         console.log('Processing DB transaction for > ' + item + ' ....... Done.');
         console.log('Success! Next....');
         callback(null)
       }, 5000);
    
       //this will not wait for timeout
       console.log('Timeout set. Waiting to timeout ...');
     }
    

    我会尝试使用真实数据库,而不是使用超时进行模拟。小心超时,见下文documentation

    请务必注意,您的回调可能不会被调用 在精确的延迟毫秒内 - Node.js 不保证 回调何时触发的确切时间,也不是排序的确切时间 事情会发生。回调将被尽可能接近地调用 到指定的时间。

    【讨论】:

    • 谢谢,已解决!是的,我知道每个都是并行的,这就是为什么我提到我正在尝试使用 .series。
    • 不客气,伙计。我还编辑了您的问题以包含 async.js 标记,因为您的问题是关于该库的。其他人会更容易找到有类似问题的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 2019-02-06
    相关资源
    最近更新 更多