JavaScript:异步函数中的代码会在第一个等待的承诺 运行 之前同步吗?
JavaScript: Will code in async functions before the first awaited promise run synchronously?
鉴于以下情况:
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语句之前的代码是同步执行的吗?
In other words, is the code before the first await statement executed synchronously?
是的。
在规范的 25.7.5.1 中指定:
25.7.5.1 AsyncFunctionStart ( promiseCapability, asyncFunctionBody )
[logic for resuming the execution somewhen]
Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
Resume the suspended evaluation of asyncContext. Let result be the value returned by the resumed
computation.
Assert: When we return here, asyncContext has already been removed from the execution context stack and
runningContext is the currently running execution context.
Assert: result is a normal completion with a value of undefined. The possible sources of completion values are
Await or, if the async function doesn't await anything, the step 3.g above.
当你调用异步函数时,这个操作会得到 运行,正如你所看到的,它直接执行了 asyncContext 而没有等待任何东西。但是,如果引擎达到 await
,它会主动停止执行:
6.2.3.1 Await
[set up logic to continue somewhen]
- Remove asyncContext from the execution context stack and restore the execution context that is at the top of the
execution context stack as the running execution context.
鉴于以下情况:
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语句之前的代码是同步执行的吗?
In other words, is the code before the first await statement executed synchronously?
是的。
在规范的 25.7.5.1 中指定:
25.7.5.1 AsyncFunctionStart ( promiseCapability, asyncFunctionBody )
[logic for resuming the execution somewhen]
Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
Resume the suspended evaluation of asyncContext. Let result be the value returned by the resumed computation.
Assert: When we return here, asyncContext has already been removed from the execution context stack and runningContext is the currently running execution context.
Assert: result is a normal completion with a value of undefined. The possible sources of completion values are Await or, if the async function doesn't await anything, the step 3.g above.
当你调用异步函数时,这个操作会得到 运行,正如你所看到的,它直接执行了 asyncContext 而没有等待任何东西。但是,如果引擎达到 await
,它会主动停止执行:
6.2.3.1 Await
[set up logic to continue somewhen]
- Remove asyncContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.