异步循环问题

问题描述

问题出现的环境背景及自己尝试过哪些方法

我知道事件执行的过程及机制,但一直想不到有什么优雅的写好,求指教。

相关代码

let arr = []
  for (let i = 0; i < 5; i++) {
    Promise.resolve(1).then(() => {
        console.log(i)
        arr.push(i)
    })
}
//想在arr里面获取[0,1,2,3,4] 有什么好的写法
console.log(arr)

你期待的结果是什么?实际看到的错误信息又是什么?

想在外面拿到处理后的数据

阅读 2.4k
5 个回答
const test = async ()=>{
  let arr = []
  for (let i = 0; i < 5; i++) {
    const j = await new Promise(resolve=>{
      Promise.resolve(1).then(() => {
        console.log(i);
        resolve(i)
      })
    })
    arr.push(j)
  }
console.log(arr)

}

test();

异步非顺序执行的话 就promise.all 顺序的话可以用async await 转化成 非异步

应该是这样吧

let arr = []
new Promise((resolve, reject) => {
    for (let i = 0; i < 5; i++) {
        arr.push(i)
    }
    resolve()
}).then(() => {
    // 在这里输出结果
    console.log(arr)
})

这样是不是会简洁一点:

let a = [0,1,2,3,4].reduce((pre, cur) => pre.then(res => res.concat(cur)), Promise.resolve([]))

a.then(res => console.log(res)) // [ 0, 1, 2, 3, 4 ]

WHY:for循环的Promise.resolve()为微任务队列;console.log(arr)为同步代码;同步代码会先于微任务队列执行,所以打印的结果为空数组[]。
HOW:
方式1:我们知道EventLoop中微任务可以enqueue微任务,所以可以把console.log(arr)放到一个后续的微任务中
方式2:task queue(比如定时器)会在微任务队列之后执行,可以把console.log(arr)放到setTimeout中。(不优雅)

总之,写法有很多种,熟悉EventLoop机制是根本

// 在最后加上以下代码
Promise.resolve().then(() => {
  console.log(arr)
})
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题