给定以下内容:
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
推送到执行上下文堆栈上;asyncContext 现在是正在运行的执行上下文。
恢复暂停的 asyncContext 评估。让结果是恢复返回的值 计算。
断言:当我们回到这里时,asyncContext 已经从执行上下文堆栈中删除,并且 runningContext 是当前正在运行的执行上下文。
断言:结果是值未定义的正常完成。完成值的可能来源是 等待,或者,如果异步函数不等待任何内容,则执行上面的步骤 3.g。
此操作在调用异步函数时运行,如您所见,它直接执行asyncContext,而无需等待任何内容。但是,如果引擎到达await
,它会主动停止执行:
6.2.3.1 等待
[设置逻辑以在某个时间继续]
- 从执行上下文堆栈中删除 asyncContext,并还原位于 作为正在运行的执行上下文的执行上下文堆栈。