Nodejs 如何使用async.js来实现循环插入数据到数据库并统一汇总操作结果后返回

Nodejs 如何使用async.js来实现循环插入数据到数据库并统一汇总操作结果后返回

大家好,我现在想把一组数据插入数据库中,并且在全部插入数据后统一返回所有数据的插入结果,我听说可以用async.js来实现,但不知道如何使用,请帮一下了。下面是我的一些示例代码,现通过data.length来判读是否执行到最后一条插入命令,但这样是不能保证真正是执行到最后一条的,需要用async.js来重写,请帮忙一下。谢谢!

var data = [ {pid: 1, syncid: ‘a’}, {pid: 2, syncid: ‘b’}, {pid: 3, syncid: ‘c’} ];

function save(table, dataObject, pcallback) { var sql = ‘INSERT INTO ’ + table + ’ SET ?’; pool.acquire(function (error, client) { if (error) { // handle error - this is generally the err from your // factory.create function pcallback(error, null); } else { client.query(sql, dataObject, function (error, rows) { // return object back to pool client.release(); // console.log(‘from callback:’+ee()); pcallback(error, rows); }); } }); }

function callbackFactory(res, syncid, islast) { return function callback(err, result) { if (err) { console.log(‘err:’ + err); //throw err; } result.syncid = syncid; res.write(result.syncid + ‘,’); if (islast) { res.end(); } }; }

function sync_fee(data, res) { var i, pid, syncid, params, islast, callback; for (i = 0; i < data.length; i += 1) { pid = data[i].pid; syncid = data[i].syncid; params = {pid: pid, syncid: syncid}; islast = (i === data.length - 1); callback = callbackFactory(res, syncid, islast); save(‘tfee’, params, callback); } }


5 回复

当然可以,我们可以使用 async.js 库中的 eachSeries 方法来按顺序处理数组中的每一项,并确保所有的异步操作完成后才返回结果。下面是具体的实现方式:

首先,确保你已经安装了 async.js 库。如果没有安装,可以通过 npm 安装:

npm install async

接下来是修改后的代码:

示例代码

const async = require('async');
const pool = require('./dbPool'); // 假设这是你的数据库连接池模块

var data = [
    { pid: 1, syncid: 'a' },
    { pid: 2, syncid: 'b' },
    { pid: 3, syncid: 'c' }
];

function save(table, dataObject, pcallback) {
    var sql = 'INSERT INTO ' + table + ' SET ?';
    pool.acquire(function (error, client) {
        if (error) {
            pcallback(error, null);
        } else {
            client.query(sql, dataObject, function (error, rows) {
                client.release();
                pcallback(error, rows);
            });
        }
    });
}

function callbackFactory(res, syncid, islast) {
    return function callback(err, result) {
        if (err) {
            console.log('err:' + err);
        }
        result.syncid = syncid;
        res.write(result.syncid + ',');
        if (islast) {
            res.end();
        }
    };
}

function sync_fee(data, res) {
    async.eachSeries(data, function(item, eachCallback) {
        const { pid, syncid } = item;
        const params = { pid, syncid };
        const islast = data.indexOf(item) === data.length - 1;
        const callback = callbackFactory(res, syncid, islast);

        save('tfee', params, function(err, result) {
            if (err) {
                eachCallback(err);
            } else {
                eachCallback(null, result);
            }
        });
    }, function(err) {
        if (err) {
            console.error('Error during insertion:', err);
            res.end('Error during insertion');
        } else {
            res.end('All data inserted successfully');
        }
    });
}

// 假设这是一个HTTP响应的回调函数
function httpResponseHandler(req, res) {
    sync_fee(data, res);
}

module.exports = httpResponseHandler;

解释

  1. 引入 async.js:

    const async = require('async');
    
  2. 定义 sync_fee 函数:

    • 使用 async.eachSeries 遍历 data 数组。
    • 对于数组中的每个元素,调用 save 函数进行数据库插入操作。
    • 每次插入操作完成后,调用 callbackFactory 创建一个回调函数,并传递给 save 函数。
  3. callbackFactory 函数:

    • 创建一个回调函数,用于处理每个插入操作的结果,并根据当前插入操作是否为最后一个操作来决定是否结束响应。
  4. save 函数:

    • 这个函数负责执行数据库插入操作,并在完成时调用回调函数。
  5. 错误处理:

    • async.eachSeries 的最终回调函数中处理可能发生的错误,并在响应中返回相应的信息。

通过这种方式,你可以确保所有的数据都已成功插入到数据库中,并且只有在所有操作完成后才会返回最终的结果。


var opt_result = []; async.eachLimit(items, function (item, callback) { do_your_db_opt(item, function(){ opt_result.push(item_result); callback(); }); }, function (err) { review_your_result(opt_result); });

谢谢,现在可以了,我用map来实现,map不需要自定义一个数据来接收返回值,在他的回调函数中会把每次的返回值都存起来,一次性返回。

代码类似这样: exports.sync=function(requestcode,data,res,next){ async.mapLimit(data,10,function(item,callback){ if(item.pid!=undefined || item.pid!=’’){ callback(null,item.pid); //判断传入的数据,每次返回pid值 }else{
callback(null,item.name); //判断传入的数据,每次返回name值
} },function(err,results){ res.send(results.join()); //异步执行完data数组中的所有数据后,把每次调用的结果自动组合成数组一次性返回 }); return next(); }

为了使用 async.js 实现循环插入数据到数据库并统一汇总操作结果后返回,我们可以使用 async.eachSeries 方法。该方法可以确保数组中的每个元素都按顺序处理,并且只有在完成当前元素的操作后才会处理下一个元素。

以下是修改后的代码示例:

const async = require('async');
const pool = require('./databasePool'); // 假设这是你的数据库连接池

var data = [
  { pid: 1, syncid: 'a' },
  { pid: 2, syncid: 'b' },
  { pid: 3, syncid: 'c' }
];

function save(table, dataObject, pcallback) {
  const sql = 'INSERT INTO ' + table + ' SET ?';
  pool.acquire(function (error, client) {
    if (error) {
      pcallback(error, null);
    } else {
      client.query(sql, dataObject, function (error, rows) {
        client.release();
        pcallback(error, rows);
      });
    }
  });
}

function callbackFactory(res, syncid, islast) {
  return function callback(err, result) {
    if (err) {
      console.log('err:' + err);
    }
    result.syncid = syncid;
    res.write(result.syncid + ',');
    if (islast) {
      res.end();
    }
  };
}

function sync_fee(data, res) {
  async.eachSeries(data, (item, callback) => {
    const { pid, syncid } = item;
    const params = { pid, syncid };
    save('tfee', params, (err, result) => {
      callback(err);
    });
  }, (err) => {
    if (err) {
      console.log('An error occurred:', err);
    } else {
      res.end(); // 所有数据已成功插入
    }
  });
}

// 使用示例
const res = {
  write: (chunk) => console.log(chunk),
  end: () => console.log('All data inserted.')
};

sync_fee(data, res);

在这个示例中,async.eachSeries 确保 data 数组中的每个元素按顺序处理。save 函数用于执行插入操作,并在回调函数中调用 callback 来表示当前元素的处理完成。当所有元素处理完成后,最终的回调函数会被调用,此时所有的插入操作已经完成,可以返回汇总的结果。

回到顶部