node.js - Nodejs:有限的并行执行在处理结束时挂起
问题描述
我正在根据这个问题处理一些文件。我的代码如下所示:
const procFile = async (url) => {
await download(url);
await convert(url);
await upload(url);
};
const thread = async (urls) => {
while (urls.length) {
await procFile(urls.pop());
}
};
const start = async (urls) => {
const threads = [];
const maxConcurrency = 4;
for (let _ of new Array(maxConcurrency)) {
threads.push(thread(urls));
}
await Promise.all(threads);
}
每当我设置maxConcurrency
一个大于1的vlue时,程序最终都会挂起,值越大maxConcurrency
挂起的越快。程序陷入emitHook
了 NodeJs 核心模块方法内部的无限循环async_hooks
。
使用Node 14
谢谢你的帮助。
解决方案
使用纯 JS 的简单并发(现场演示):
function concurrency(arr, map, limit){
let pendingCount= 0;
const results= [];
return new Promise((resolve, reject)=>{
function pump(){
while (arr && arr.length && pendingCount < limit) {
pendingCount++;
map(arr.shift()).then(result=>{
pendingCount--;
results.push(result);
pump();
}, err=> {
arr= null;
reject(err)
});
}
if(!pendingCount){
return resolve(results);
}
}
pump();
})
}
concurrency([
'url1',
'url2',
'url3',
'url4',
'url5',
'url6',
], async(url)=>{
await download(url);
await convert(url);
return upload(url);
}, 2).then(results=> console.log(`Results: `, results));
或者您可以尝试使用任何具有并发限制功能的库,例如Bluebird.js、p-limit、CPromise (现场演示)
const CPromise= require('c-promise2');
async function download(url){
console.log(`download ${url}`);
return CPromise.delay(1000)
}
async function convert(url){
console.log(`convert ${url}`)
}
async function upload(url){
console.log(`upload ${url}`)
}
(async()=>{
await CPromise.all([
'url1',
'url2',
'url3',
'url4',
'url5',
'url6',
], {
mapper: async (url) => {
await download(url);
await convert(url);
await upload(url);
},
concurrency: 2
})
console.log('Done');
})();
推荐阅读
- java - 如何在不实际重新加载 JSP 页面的情况下单击下一个/上一个按钮逐个打印数据(arraylist 的对象)?
- google-sheets - 如何在 Google Data Studio 中同时使用 SUM () 和 CASE () 计算总金额?
- java - 使用 Lucene Query 测试文档是否匹配
- php - 如何将验证码添加到邮件表单
- react-native - 如何在本机反应中渲染json对象中的所有项目?
- hibernate - 如何在使用 Hibernate 实现查询时获取连接表的属性以检查字符串是否等于它
- javascript - 运行 Angular 7 项目的问题
- jquery - Firefox 无法查看 img 标签
- visual-studio - 我的 csproj 文件参考中是否需要有提示路径?
- javascript - 如何清除 aurelia 中的文件输入绑定