(我的目标是阐明我对此问题的概念,而不是代码)
我想按顺序执行一个promise数组,但是nodeJS抛出了一个关于许多并行执行的promise的奇怪错误(因为我将数组限制为20个promise和Works,50个promise和works,但是9000个promise和爆炸。)
我的问题:我可以执行20个诺言,然后再执行20个诺言,依此类推,但是... 如果我按顺序执行我的诺言,nodeJS必须执行9k个诺言没有问题吗?我的观念不好吗?我的代码不正确?
(令人怀疑,因为nodeJS在开始兑现承诺之前要等待一段时间)
我的情况:我尝试下载9k +图像(使用axios),然后保存每个图像,然后依次等待5秒钟。 [下载1张图像,保存该图像,等待5秒钟,然后下载下一张图像,保存..,等待...,等等。]可能吗?
答案 0 :(得分:1)
我本来会使用worker pool之类的东西,而不是每次都以20个批处理来执行,所以您总是要等到最后一个处理完才开始下一个20个批处理,而应该设置限制您要执行的连续下载的数量,因此您的承诺不超过20个,而且没有9000个长链
同样的事情也可以通过迭代器来完成。 (可以将同一迭代器传递给不同的工作人员,而当某人调用第一个项目时,下一个工作人员将始终获得下一个工作人员)
所以在零依赖的情况下,我会做这样的事情:
const sleep = n => new Promise(rs => setTimeout(rs, 1000))
async function sequentialDownload(iterator) {
for (let [index, url] of iterator) {
// figure out where to save the file
const path = path.resolve(__dirname, 'images', index + '.jpg')
// download all images as a stream
const res = await axios.get(index, { responseType: 'stream' })
// pipe the stream to disc
const writer = fs.createWriteStream(path)
res.data.pipe(writer)
// wait for the download to complete
await new Promise(resolve => writer.on('finish', resolve))
// wait a extra 5 sec
await sleep(5000)
}
}
const arr = [url1, url2, url3] // to be downloaded
const workers = new Array(20) // create 20 "workers"
.fill(arr.entries()) // fill it with same iterator
.map(sequentialDownload) // start working
Promise.all(workers).then(() => {
console.log('done downloading everything')
})