如何串行执行多个promise

发布于 2022-09-11 21:18:39 字数 1028 浏览 13 评论 0

只使用promise语法。不使用async、await等语法。

PS:网上广为流传的使用reduce实现多个promise串行执行只对同步promise生效。

function start(tasks){
  var result = []
  return tasks.reduce((accumulator,item,index)=>{
    return item.then(res=>{
      result[index] = res
      return index == tasks.length - 1 ? result : item
    })
  },Promise.resolve())
}
start([
  Promise.resolve(1),
  Promise.resolve(2),
  Promise.resolve(3)
]).then(res=>{
  console.log(res) //[1,2,3]
})

串行执行成功

function start(tasks){
  var result = []
  return tasks.reduce((accumulator,item,index)=>{
    return item.then(res=>{
      result[index] = res
      return index == tasks.length - 1 ? result : item
    })
  },Promise.resolve())
}
function delay(time){
  return new Promise(function(resolve,reject){
    setTimeout(function(){
      resolve(time)
    },time)
  })
}

start([
  delay(2000),
  delay(2000),
  delay(1000)
]).then(res=>{
  console.log(res) //[undefined,undefined,1000]
})

串行执行不成功

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

浅语花开 2022-09-18 21:18:39

reduce实现多个promise串行执行的关键在于不断的在accumulator后面追加then,你这里缺少了,应该改为

function start(tasks){
      var result = []
      return tasks.reduce((accumulator,item,index)=>{
        return accumulator.then(res=>{
            return item.then(res=>{
                  result[index] = res
                  return index == tasks.length - 1 ? result : item
            })
        })
      },Promise.resolve())
}
玩世 2022-09-18 21:18:39

你的问题不在于没有串行执行,而是在声明

[
  delay(2000),
  delay(2000),
  delay(1000)
]

的时候代码已经开始执行了,所有的计时器已经被激活了了。所以无论start怎么做,你都没法得到等5秒完成所有任务的结果。

遗心遗梦遗幸福 2022-09-18 21:18:39

概念问题
创建一个promise时已经“开始执行”了
promise创建后,能做的只是 “等待执行完成”

七颜 2022-09-18 21:18:39

其实这个问题在于 因为你执行的delay是异步的... 在reduce的过程中他们每个方法都被赋予了一个浅层次index...
然后同一时间都在等then的触发... 谁快执行谁... 这时候最后一个1000ms的先完事了...正好它的 index == tasks.length - 1 然后就把result返回了 这时候就是[undefined,undefined,1000] 因为这时候前两个还没完事呢...

豆芽 2022-09-18 21:18:39

改变一下写法就好

function start(tasks) {
    var result = [];
    return tasks.reduce((accumulator, item, index) => {
    return accumulator.then(res => {
      result.push(res);
      return index == tasks.length - 1 ? item.then(res => { result.push(res); return result; }) : item;
    });
    }, Promise.resolve(0));
}

function delay(time) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(time);
        }, time);
    });
}

start([delay(3000), delay(2000), delay(1000)]).then(res => {
    console.log(res); // [0, 3000, 2000, 1000]
});
神爱温柔 2022-09-18 21:18:39

我没理解错的话,你只需要保证结果有序,并不需要保证执行有序,所以一个promise.all就搞定了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文