NodeJS:如何使用异步.js来处理数据库中的项目列表

NodeJS: How to use async.js to process a list of items in database

本文关键字:数据库 项目 列表 处理 何使用 异步 js NodeJS      更新时间:2023-09-26

我有这个问题:我从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.each 的异步文档

将函数迭代并行应用于 arr 中的每个项。

看,他们甚至警告说,这并不能保持顺序,因为它是平行的:

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

如果我理解正确,您希望您的项目(假设您有 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 ...');
 }

我会尝试使用真实的数据库,而不是使用超时进行模拟。小心超时,请参阅下面的文档:

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

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