javascript的异步功能实际上是同步的吗?

时间:2019-09-12 11:43:16

标签: javascript node.js asynchronous async-await

我试图弄清楚异步代码如何在Javascript中工作。现在,我知道JS中实际上只有一个线程执行队列中的作业,并且只有在当前作业完成时(即,如果所有同步代码或异步函数都完成了),它才可以开始执行下一个作业。

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

中。

首先,我们使用async关键字表示函数。那么,是否意味着这些功能将被放入队列中的单独作业中,并在将来的某个位置执行?好吧,事实证明答案是。但是请耐心等待,正如我将要解释的。

据我所知,从理论上讲,JS线程应该首先执行所有同步代码,直到完成为止,同时将所有异步函数,promise和回调函数的执行延迟到工作的最后,从而将其执行队列。然后,一旦所有同步代码完成,它将开始执行所有堆积的工作。

所以,如果我有以下代码:

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");

那么从理论上讲,它应该首先执行所有同步代码,然后才开始执行异步功能,然后执行回调:

starting sync code
sync code completed
executing async function
executing callback of async function

但是现实是不同的!实际上,它实际上与其他同步代码一起同步执行异步功能 。真正放入作业队列的唯一位是异步函数的回调

starting sync code
executing async function
sync code completed
executing callback of async function

那是什么意思? async函数实际上是谎言吗?看起来如此,因为它们实际上是正常,同步函数,您可能碰巧将 async 回调附加到该函数。

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

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

是以下语言的语法糖:

function asyncFunc() {
    return new Promise((resolve) => {
        console.log("executing async function");
        resolve();
    });
}

但是我的观点仍然存在。您传递给promise的所谓异步函数实际上是同步执行的。好吧,从技术上讲Promise对象并不意味着它将异步执行,而async关键字却可以!因此,它是完全错误的信息,它使您相信它是异步的,而事实证明并非如此。

2 个答案:

答案 0 :(得分:4)

就像构造Promise一样,在async函数中遇到任何await函数内同步的任何事物都将同步执行。 async函数仅会在遇到await时停止执行其代码-在此之前,它也可能是正常的非async函数(除非它会将返回值包装在Promise中)。

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");

如您在上面的代码段中所见,一旦asyncFunc1的{​​{1}}(并且调用了所有 synchronous 代码, asyncFunc1)完成。

await是一个关键字,允许您在函数内部使用await,但实际上 并不意味着其他任何意思,它只是一个关键字。函数甚至可以同步运行其所有代码(尽管有点奇怪)。

答案 1 :(得分:0)

只是证明我的观点和@CertainPerformance的观点。 这是一个具有睡眠功能的示例,该功能在等待解决之前等待500毫秒:

async function sleep(msec) {
  return new Promise(resolve => setTimeout(resolve, msec));
}

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

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

这里只有console.log:

async function sleep(msec) {
  console.log('test');
} 

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

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