JavaScript:在第一个等待的承诺之前,异步函数中的代码会同步运行吗?



给定以下内容:

function defer(delay) {
return new Promise((resolve) => setTimeout(resolve, delay));
}
let a;
(async () => {
a = 1;
await defer(1000);
a = 2;
})();
console.log(a); // 1

我是否可以保证在所有引擎和转换中,异步函数调用后的a值是1的,而不是未定义的?换句话说,第一个 await 语句之前的代码是否同步执行?

换句话说

,第一个 await 语句之前的代码是否同步执行?

是的。

它在规范的 25.7.5.1 中指定:

25.7.5.1 AsyncFunctionStart ( promiseCapability, asyncFunctionBody )

[在某个时候恢复执行的逻辑]

    将 asyncContext
  1. 推送到执行上下文堆栈上;asyncContext 现在是正在运行的执行上下文。

  2. 恢复暂停的 asyncContext 评估。让结果是恢复返回的值 计算。

  3. 断言:当我们回到这里时,asyncContext 已经从执行上下文堆栈中删除,并且 runningContext 是当前正在运行的执行上下文。

  4. 断言:结果是值未定义的正常完成。完成值的可能来源是 等待,或者,如果异步函数不等待任何内容,则执行上面的步骤 3.g。

此操作在调用异步函数时运行,如您所见,它直接执行asyncContext,而无需等待任何内容。但是,如果引擎到达await,它会主动停止执行:

6.2.3.1 等待

[设置逻辑以在某个时间继续]

  1. 从执行上下文堆栈中删除 asyncContext,并还原位于 作为正在运行的执行上下文的执行上下文堆栈。

最新更新