所以我创建了一个收集数据并在永无止境的循环中将其写入db的服务器。
server.listen(3001, () => {
doFullScan();
});
async function doFullScan() {
while (true) {
await collectAllData();
}
}
collectAllData()
是一种检查可用项目的方法,循环遍历每个项目收集一些数据并将其写入db。
async function collectAllData() {
//doing soemhting
const projectNames = ['array with projects name'];
//this loop takes too much of time
for(let project in projectNames){
await collectProjectData(project);
}
//doing something
}
问题是整个循环花费了太多时间。所以我想通过多线程循环加速它并使用我的所有计算机核心。
我该怎么办?
在https://nodejs.org/docs/latest/api/cluster.html上有一些包含示例的集群库,但我不想创建新的服务器。我想产生儿童,这将完成任务并在完成工作后退出。
所以有const { fork } = require('child_process');
但我不确定如何让每个fork只运行collectProjectData()
方法。
答案 0 :(得分:1)
您可以在没有任何第三方库的情况下本地执行此操作。
现在,您的for...loop
正在逐个运行。
使用Promise.all
和.map
await Promise.all(projectNames.map(async(projectName) => {
await collectProjectData(projectName);
});
请注意,如果您使用.map
,它将同时启动所有这些,如果projectNames
继续增长,则可能会过多。
这与你目前所做的完全相反。
有一个中间方式......按顺序运行批次,但是每个批次内的项目是异步的。
const chunk = (a, l) => a.length === 0 ? [] : [a.slice(0, l)].concat(chunk(a.slice(l), l));
const batchSize = 10;
const projectNames = ['array with projects name'];
let projectNamesInChunks = chunk(projectNames, batchSize);
for(let chunk of projectNamesInChunks){
await Promise.all(chunk.map(async(projectName) => {
await collectProjectData(projectName);
});
}
答案 1 :(得分:0)
我建议使用Promise.map http://bluebirdjs.com/docs/api/promise.map.html
这样你就可以像这样控制并发级别:
await Promise.map(projectNames, collectProjectData, {concurrency: 3})