解决Node.js循环并发问题

2019-12-23  本文已影响0人  浥羽醉悠扬

之前用express框架完成个需求,每日定时对数据进行汇总,有了如下代码(示例代码)

const schedule = require("node-schedule");

const summary = async (args) => {
    // 进行汇总
});

schedule.scheduleJob('0 0 3 * * *', async () => {
  // 每天三点调用summary ()
  for (let i = 0; i < num; i ++) {
        await summary(args)
    }
});

这样能完成需求,但是这样只能逐条执行,效率很低,随着需要汇总的数据越来越多,这种写法很快就会变得不可用。于是对定时任务做了如下修改:

schedule.scheduleJob('0 0 3 * * *', async () => {
  const proList = [];
  let ret;
  for (let i = 0; i < num; i ++) {
      ret = summary(args)
      proList.push(ret);
    }
  await Promise.all(proList);
});

按照ES6推荐写法做出如上改动,这样会全部并发,随之带来新的问题:如果程序运行时与数据库建立的连接数,超过设置的最大连接数,超出部分不会执行,同样不符合使用场景。

开发阶段数据库连接数限制设置为2,很快发现了问题,并一度认为这种思路从根源就是错误的,其实不然。

接下来需要做的就是,结合上述代码分多次进行promise.all()。

    const BASE = 50; // 偏移量
    for (let i = 0; i < num; i += BASE) {
        // 对查询结果sqlres进行分割
        let block = sqlres.slice(i, i + BASE);
        await Promise.all(block.map(async (item) => {
            await summary(args);
        }))
    }

从查询结果中每次固定取出BASE个结果,BASE的数值要<连接数据库的限制数。这样就完成了分多次并发,完成效率与负荷的兼顾。

完结撒花。

上一篇下一篇

猜你喜欢

热点阅读