javascript 的异步函数实际上是同步的吗?

Yev*_*i N 3 javascript asynchronous node.js async-await

我想弄清楚异步代码在 Javascript 中是如何工作的。现在,我明白在 JS 中实际上有一个线程执行队列中的作业,并且只有在当前作业完成后(即如果所有同步代码或异步函数都完成),它才能开始执行下一个作业.

现在,令人困惑的部分是实际算作异步函数的部分 - 实际放入队列中单独作业的内容,以及未放入的内容。

首先,我们有async函数的关键字。那么这是否意味着这些函数将被放入队列中的一个单独的作业中并在将来的某个地方执行?好吧,事实证明答案是否定的。但请耐心等待,我将解释。

据我所知,理论上,JS 线程应该首先执行所有同步代码,直到它完成,同时通过将它们作为作业放置到队列末尾来延迟所有异步函数、承诺和回调的执行。然后,一旦所有同步代码完成,它将开始执行所有堆积的工作。

所以如果我有以下代码:

async function asyncFunc() {
    console.log("executing async function");
}

console.log("starting sync code");
asyncFunc().then(() => {
    console.log("executing callback of async function")
});
console.log("sync code completed");
Run Code Online (Sandbox Code Playgroud)

那么理论上,它应该先执行所有同步代码,然后才开始执行异步函数,然后是回调:

starting sync code
sync code completed
executing async function
executing callback of async function
Run Code Online (Sandbox Code Playgroud)

但现实是不同的!实际上,它实际上是同步执行 async 函数,以及其余的同步代码。实际放入作业队列的唯一位是异步函数的回调

starting sync code
executing async function
sync code completed
executing callback of async function
Run Code Online (Sandbox Code Playgroud)

那是什么意思呢?那个async函数其实是骗人的?看起来是这样,因为它们实际上是正常的同步函数,您可能会碰巧将异步回调附加到其中。

现在,我知道这async实际上是返回 a 的函数的语法糖Promise,例如:

async function asyncFunc() {
    console.log("executing async function");
}
Run Code Online (Sandbox Code Playgroud)

是语法糖:

function asyncFunc() {
    return new Promise((resolve) => {
        console.log("executing async function");
        resolve();
    });
}
Run Code Online (Sandbox Code Playgroud)

但我的观点仍然存在。您传递给承诺的所谓异步函数实际上是同步执行的。好吧,从技术上讲,该Promise对象并不意味着它将异步执行,但async关键字确实如此!所以这是彻头彻尾的错误信息,它让你相信它是异步的,而事实证明它不是。

Cer*_*nce 7

就像构造 Promise 时一样,遇到任何s之前async函数内部的任何同步都会同步执行。一个功能只会停止执行其代码,一旦遇到-直到那时,它也可以被正常的非功能(除了一个事实,即它会包裹在无极的返回值)。awaitasyncawaitasync

async function asyncFunc2() {
  console.log("in Async function 2");
}
async function asyncFunc1() {
  console.log("in Async function 1");
  await asyncFunc2();
  console.log('After an await');
}
console.log("starting sync code");
asyncFunc1().then(() => {
  console.log("Received answer from async code");
});
console.log("finishing sync code");
Run Code Online (Sandbox Code Playgroud)

正如你可以在上面的代码段看到,主线程仅恢复以外asyncFunc1一次asyncFunc1await(和所有同步由调用代码await)完成。

async是一个允许您await在函数内部使用的关键字,但它本质上并不意味着其他任何东西,实际上 - 它只是一个关键字。该功能可以甚至可以运行所有的代码的同步(虽然这会是一种奇怪的看)。

  • 是的,这使得它们不是真正的“异步”函数,而是“仅在行后与等待关键字(如果存在)异步”函数。 (3认同)