猿问

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

我想弄清楚异步代码在 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

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


starting sync code

executing async function

sync code completed

executing callback of async function

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


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


async function asyncFunc() {

    console.log("executing async function");

}

是语法糖:


function asyncFunc() {

    return new Promise((resolve) => {

        console.log("executing async function");

        resolve();

    });

}

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


慕后森
浏览 320回答 3
3回答

隔江千里

就像构造 Promise 时一样,在遇到任何s之前,async函数内部的任何同步都会同步执行。一个功能只会停止执行其代码,一旦遇到-直到那时,它也可以被正常的非功能(除了一个事实,即它会包裹在无极的返回值)。awaitasyncawaitasyncasync 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一次asyncFunc1的await(和所有同步由调用代码await)完成。async是一个允许您await在函数内部使用的关键字,但它本质上并不意味着其他任何东西,实际上 - 它只是一个关键字。该功能可以甚至可以运行所有的代码的同步(虽然这会是一种奇怪的看)。

慕田峪7331174

只是为了证明我和@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");
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答