NodeJS:如何使用async.js处理数据库中的项列表

时间:2016-02-14 16:53:57

标签: javascript node.js asynchronous async.js

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

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

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。

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

2 个答案:

答案 0 :(得分:1)

基于使用async.each

的异步documentation
  

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

看起来他们甚至警告说,这并不保留订单,因为它是平行的:

  

注意,因为此函数将iteratee应用于每个项目   并行,不能保证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不保证   回调将触发的确切时间,也不是排序   事情会发生。回调将尽可能接近   到指定的时间。

答案 1 :(得分:0)

    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);
    });