【问题标题】:How can await promise resolve if resolve(...) is inside setTimeout?如果resolve(...) 在setTimeout 内,await promise 如何解决?
【发布时间】:2021-07-10 01:50:28
【问题描述】:

下面代码的执行顺序是什么?

如果 await 让我们等待“promise”解决,但 resolve(...) 在 setTimeout 内,并且 setTimeout 仅在堆栈为空后才执行...我们如何不冻结在 await 上?当我们“等待”时,堆栈上还没有东西吗? await-y setTimeout 是否有一些例外,或者我不理解堆栈?

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  let result = await promise; // wait until the promise resolves (*)

  alert(result); // "done!"
}


f();

【问题讨论】:

    标签: javascript asynchronous async-await stack queue


    【解决方案1】:

    await 基本上是.then 的替代品——它说“只有在 Promise 解决后才做剩下的事情”。它不会在 await 处冻结解释器 - 它只会暂停当前函数的执行流程,直到 Promise 解决。

    所以

    // wait until the promise resolves (*)
    

    可能更准确地理解为

    // pause execution of this function until the promise resolves (*)
    

    当我们“等待”时,堆栈上是否还有东西?

    是的,f() 在等待 await promise 解析时同步返回一个 Promise(来自 async 函数)。然后脚本不做任何其他事情,因此调用堆栈完全为空,直到一秒钟后setTimeout 宏任务运行,添加了一个调用resolve 的短任务,该任务将一个微任务排队,很快导致done 成为记录。

    在您的代码中有很多次没有当前活动的任务。

    【讨论】:

    • 您好,感谢您的回复 - 它有帮助。所以......如果在我的代码的最后一行之后有更多代码('f();'下面的东西) - 是否必须在等待承诺得到解决之前执行?如果是这样,那是因为'let result = await ...'就像一个.then处理程序和setTimeout吗?如果你有一分钟​​的时间,你能否告诉我这些“在你的代码中没有当前活动任务的次数”。很抱歉所有问题 - 你已经非常有帮助了。
    • 没错。一旦在函数内部到达await,函数就会暂停并(1)等待它下面的所有其他同步代码完成(2)等待超时以产生一个新的宏任务(3)当宏任务运行时,@987654332调用@,向队列中添加一个新任务,该任务在所有其他同步代码运行后不久运行
    • 暂停在 (1) 和 (2) 之间(例如 0.5 秒后,等待超时)以及在 (2) 和 (3) 之间(在调用 resolve 之后,当调用堆栈上没有任何内容。然后,一个单独的任务(Promise 的微任务)运行并继续执行,导致 alert(result); 正在运行。
    猜你喜欢
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 2021-05-19
    • 2021-09-12
    • 2023-02-15
    • 2019-08-13
    相关资源
    最近更新 更多