解决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的数值要<连接数据库的限制数。这样就完成了分多次并发,完成效率与负荷的兼顾。
完结撒花。