JavaScript Promise 如何与 setTimeout 配合? [重复]

问题描述 投票:0回答:1

我有一个关于 JavaScript Promise 以及与 setTimeout 一起使用时 then() 方法的执行顺序的问题。以下是有问题的代码:

new Promise((resolve) => setTimeout(resolve, 10000, "Resolved!")).then(console.log);

我关心的是 then() 方法是否会在计时器完成之前执行。我最初认为,由于 JavaScript 引擎的工作方式,then() 会在计时器之前执行。以下是我对这个过程的理解:

  1. Promise 被创建,并且执行器函数被传递给它。
  2. 执行器函数同步执行。
  3. Promise 执行器函数设置了一个 setTimeout,它由浏览器环境的其他部分处理,而不是 JS 引擎本身。
  4. 一旦定时器到期,传递给 setTimeout 的回调将被推送到宏任务队列。
  5. 但是,由于 setTimeout 需要很长时间才能完成,因此 JS 引擎会移至 then 块。
  6. 执行then()方法,并将回调推送到微任务队列。
  7. 在调用堆栈为空的情况下,JS 引擎首先检查队列中是否有微任务。
  8. 它遇到 then() 中的函数并执行它。
  9. 在未来的某个时刻,setTimeout 完成执行并将回调推送到宏任务队列。
  10. JS 引擎然后看到回调并执行它,从而解决了 Promise。

但是当我运行代码时,看来我的理解是错误的。有人可以帮助我更好地理解这个主题吗?非常感谢您的帮助。谢谢你! 以下是我找到的 Stack Overflow 答案,它消除了我的一些疑虑: https://stackoverflow.com/questions/66934373/how-then-method-actually-works-in-javascript#:~:text=then()%20method%20will%20insert,get%20the%20result%20Hello% 20Stackoverflow%20

javascript asynchronous
1个回答
-1
投票

你的理解几乎是正确的,但是有一个重要的方面需要考虑:Promise 解析和微任务执行。

以下是您提供的代码所发生情况的分步说明:

  1. 使用执行器函数 (resolve) 创建一个新的 Promise => setTimeout(解决, 10000, "解决了!").
  2. executor函数设置了setTimeout,延迟10000 毫秒(10 秒)。经过指定时间(10 秒)后, 将使用值“已解决!”调用解析函数。
  3. 至此,executor函数结束,then方法为 呼唤无极。 then 方法的回调(console.log)已注册 当 Promise 得到解决时执行。
  4. Promise 现在处于待处理状态,此时的回调函数 已注册到微任务队列中。
  5. 此时,JavaScript 引擎有一个空的调用堆栈并寻找 要执行的任何微任务。它找到then方法注册的回调 并执行它。因此,值“已解决!”已记录到控制台。
  6. 10 秒延迟后,使用值调用解析函数 “解决了!”,承诺就实现了。
  7. 现在 Promise 已履行,此时的回调将移至 调用堆栈,但由于它已经执行,所以没有什么可做的, 代码执行完成。

总而言之,then 方法的回调(console.log)在计时器完成之前执行,因为回调被注册为微任务,并且 JavaScript 优先考虑微任务而不是任务(像 setTimeout 这样的宏任务)。此行为可确保微任务在下一次渲染之前执行,从而允许您以更可预测和有序的方式处理异步操作。

请记住,虽然 then 方法的回调在计时器完成之前执行,但 Promise 本身并没有得到解析,直到 10 秒延迟后通过 setTimeout 调用解析函数。

© www.soinside.com 2019 - 2024. All rights reserved.