javascript - 按顺序执行多个 Promise(概念)

标签 javascript node.js asynchronous promise axios

(我的目标是澄清我对问题的概念,而不是代码)

我想按顺序执行一系列 Promise,但是 NodeJS 抛出了一个关于并行执行的许多 Promise 的奇怪错误。(因为我将该数组限制为 20 个 Promise 并有效,50 个 Promise 并有效,但 9000 个 Promise 并爆炸..)

  • 我知道我们有一些解决方案,例如 array.reduce()、循环等
  • 我了解 Promise 状态(我的数组最初有待处理的 Promise)

我的问题:我可以执行 20 个 Promise,然后再执行 20 个 Promise,等等,但是... 如果我按顺序执行我的 Promise,nodeJS 必须毫无问题地执行 9k 个 Promise?我有一个不好的概念?我的代码错了?

(我很怀疑,因为 NodeJS 在开始解决 promise 之前等待了一段时间)

我的情况:我尝试下载 9k+ 图像(使用 axios),然后保存每个图像,然后依次等待 5 秒。 [下载 1 个图像,保存该图像,等待 5 秒,然后下载下一个图像,保存..,等待...,等等..] 可能吗?

最佳答案

我会使用类似 worker pool 的东西与其每次执行一批 20 个任务,您总是会等待最后一个完成,然后再开始下一个 20 个批处理,相反,您应该设置一个限制,限制您想要执行的连续下载次数,这样您就没有超过 20 个 promise ,而不是 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')
})

关于javascript - 按顺序执行多个 Promise(概念),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54024495/

相关文章:

ios - 调度组 : for-loop *and* async calls within the for-loop

node.js - 仅使用 Sequelize 日志记录 SQL 以进行审计日志记录?

javascript - Lodash 与 Mongoose 合并

javascript - 以旋转轮播样式向 div 添加类

javascript - Expressjs 重新路由

angularjs - 在 angularjs 中的每个 View 加载上创建与 socket.io 的新连接

javascript - Node.js:异步回调困惑

java - 理解java play中的异步调用

javascript - ReactJS 应用程序正确处理输入值

javascript - iOS 5 Mobile Safari 应用程序缓存更改?