如何让异步操作顺序执行

如果我有一个数组[1, 2, 3, 4],如何利用promise,在每隔一秒,输出一个数字。用下面的代码会在一秒后,顺序输出1,2,3,4,大神能解释一下原因吗?

var arr = [1, 2, 3, 4]
var promises = []

arr.map(async (value) => {
  promises.push(new Promise((res) => {
    setTimeout(() => {
      console.log(value)
      res()
    }, 1000)
  }))
})

var promise = Promise.resolve()

for (var i = 0; i < promises.length; i += 1) {
  const task = promises[i]
  promise
    .then(() => {
      return task
    })
}
阅读 3.8k
评论 2017-08-19 提问
    4 个回答
    CRIMX
    • 8.9k

    一定要记得 new Promise(executor) 的 executor 是马上执行的。

    所以要么你递增 timeout 的时间,要么在一个 Promise resolved 之后再创建新的 Promise。

    arr.reduce((p, x) => p.then(() => new Promise(r => setTimeout(() => r(console.log(x)), 1000))), Promise.resolve())
    评论 赞赏
      justjavac
      • 46.7k

      推荐你看看这个:Google 前端技术专家写的 JavaScript Promise:简介。在创建序列章节,你可以找到答案。

      评论 赞赏
        wupengyu
        • 1.7k

        哦哦,刚才又分析了一下,其实上面的方法已经做到了顺序执行了。在1秒后,四个timeout方法会顺序执行1,2,3,4这样的结果其实是正确的,因为我们新定义的四个setTimeout都是在1秒后执行。

        评论 赞赏
          junlu
          • 149

          推荐使用 https://github.com/jun-lu/pro...

          可以并行,串行,并行+串行的多种组合方式

          
            new PromiseAsync( Promise.resolve(1), Promise.resolve(2))
            .flat((n1, n2)=>{
              return Promise.resolve(n1 + n2);
            })
            .subscribe((data)=>{
              // data=3...
            })
            .start()
          
          评论 赞赏
            撰写回答

            登录后参与交流、获取后续更新提醒