简体   繁体   English

顺序执行许多承诺(概念)

[英]Execute many promises sequentially (Concept)

(My target is clarify my concept about the problem, not code) (我的目标是阐明有关问题的概念,而不是代码)

I want execute a array of promises sequentially, but nodeJS throw a strange error about many promises executed in parallel.(Because i limited that array to 20 promises and works, 50 promises and works, but 9000 promises and explode..) 我想按顺序执行一个promise数组,但是nodeJS抛出了一个关于并行执行的许多promise的奇怪错误(因为我将数组限制为20个promise和works,50个promise and works,但是9000个promise and explode。)

  • I know that we have some solutions like, array.reduce(), loops, etc 我知道我们有一些解决方案,例如array.reduce(),循环等
  • I know about the promises states (my array have pending promises initially) 我知道诺言状态(我的数组最初有未完成的诺言)

My question: I can execute 20 promises, then another 20 promises, etc but... If im executing my promises sequentially, nodeJS must execute 9k promises without problem? 我的问题:我可以执行20个Promise ,然后再执行20个Promise,依此类推 ,但是... 如果我按顺序执行我的Promise,nodeJS必须执行9k个Promise没有问题? I have a bad concept? 我的观念不好吗? My code is wrong? 我的代码错了吗?

(Im doubting because nodeJS wait some time before begin to resolve the promises) (令人怀疑,因为nodeJS在开始兑现承诺之前要等待一段时间)

My case: i trying download 9k+ images (with axios), then save each one and then wait 5 seconds sequentially. 我的情况:我尝试下载9k +图像(使用axios),然后保存每个图像,然后依次等待5秒钟。 [download 1 image, save that image, wait 5 seconds, then download next image, save.., wait..., etc.. ] Possible? [下载1张图像,保存该图像,等待5秒钟,然后下载下一张图像,保存..,等待...,等等。]可能吗?

I would have used something like a worker pool instead of executing things in a batch of 20 each time, you will always end up waiting for the last one to finish before you start next 20 batch, instead you should set a limit of how many continious download you want to do so you have no more then 20 promises and not a long chain of 9000 我本来会使用诸如工作池之类的方法,而不是每次执行20次批处理,您总是会在等待下一个批处理开始之前总是等待最后一个完成,而应该设置连续多少次的限制下载要执行的操作,这样您就不会超过20个承诺,而且没有9000个长链

The same thing can be accomplish with iterators also. 迭代器也可以完成同一件事。 (a same iterator can be passed to different workers and while someone calls the first item the next worker will always get the next one) (同一个迭代器可以传递给不同的工作程序,而当某人调用第一个项目时,下一个工作程序将始终获得下一个工作程序)

So with zero dependencies i would do something like this: 因此,在零依赖性的情况下,我将执行以下操作:

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')
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM