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]

  1. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.

  2. Resume the suspended evaluation of asyncContext. Let result be the value returned by the resumed computation.

  3. Assert: When we return here, asyncContext has already been removed from the execution context stack and runningContext is the currently running execution context.

  4. 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]

  1. 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.