为了账号安全,请及时绑定邮箱和手机立即绑定

JS:我的 setTimeout 在闭包循环中出现问题

JS:我的 setTimeout 在闭包循环中出现问题

MM们 2023-11-02 17:28:59
我正在练习一些 Promise 和 Closure。我有一个forEach循环,返回一个 3 秒超时的 Promise,在 Promise 解析后,它应该记录一条语句。我认为我这样做是错误的,因为我期望每 3 秒看到一个日志,"111"然后是"222",但是我看到延迟了 3 秒,然后立即看到 3 个日志"111" "222"。let arr = [1,2,3];arr.forEach((x,i) => {  (function() {       return new Promise((resolve,reject) => {          setTimeout(() => {             console.log("111")             resolve(true)          }, 3000);       })  })()  .then(() => {console.log("222")})});
查看完整描述

1 回答

?
弑天下

TA贡献1818条经验 获得超7个赞

您只是忘记告诉 javascript 在 for 循环的每次迭代之间“等待”超时。那么发生了什么,javascript 将运行 for 循环,同时安排三个超时,然后这三个超时全部立即消失。


如果您像这样添加等待,那么它将按您的预期工作。


(async function() {

  let arr = [1, 2, 3];


  for (let x of arr) {

    await (function() { // <-- await added

      return new Promise((resolve, reject) => {

        setTimeout(() => {

          console.log("111")

          resolve(true)

        }, 3000);

      })


    })()

    .then(() => {

      console.log("222")

    })

  }

})()

我切换到 for-of,因为 .forEach() 不适用于异步函数。我还将整个内容包装在 async IIFE中,因为那里不允许顶级等待 - 根据您放置此代码的位置,您可能不必将其包装在 async IIFE 中。

编辑

刚刚意识到,您在原始问题中的任何地方都没有使用异步/等待内容。我不知道你是否已经了解了它,但你不必知道它来解决这个特定的问题。

这是另一种无需异步/等待的方法。

let arr = [1, 2, 3];


let promise = Promise.resolve();


arr.forEach((x,i) => {

  promise = promise

    .then(function() {

      return new Promise((resolve, reject) => {

        setTimeout(() => {

          console.log("111")

          resolve(true)

        }, 3000);

      })

    })

    .then(() => {

      console.log("222")

    })

});


这基本上是在循环内构建一个承诺链。如果您“展开”循环,它将如下所示:


promise = Promise.resolve()


promise = promise

  .then(() => /* wait 3000 ms and log "111" */)

  .then(() => { console.log("222") })

  .then(() => /* wait 3000 ms and log "111" */)

  .then(() => { console.log("222") })

  .then(() => /* wait 3000 ms and log "111" */)

  .then(() => { console.log("222") })

因为我们保留了对最后一个承诺的引用,并且我们不断地附加到它的末尾,所以我们附加的每件新事情都会在最后一件事情完成后发生。


查看完整回答
反对 回复 2023-11-02
  • 1 回答
  • 0 关注
  • 64 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信