我正在尝试弄清楚JavaScript中异步代码的工作原理。现在,我了解到JS实际上只有一个线程,在队列中执行作业,并且仅当当前作业完成(即所有同步代码或异步函数已经完成)时才能开始执行下一个作业。
现在,让人困惑的是,什么实际上算作异步函数-什么被放入队列中的单独作业中,什么没有。
首先,我们有函数的“async”关键字。那么这是否意味着这些函数将被放入队列中的单独作业并在将来某个时间执行?嗯,实际上答案是不。但请与我耐心解释。
据我所知,在理论上,JS线程应该从执行所有同步代码开始,直到完成,同时通过将异步函数、Promise和回调放置在队列末尾作为作业来延迟它们的执行。然后,一旦所有同步代码完成,它将开始执行所有这些堆积起来的作业。
因此,如果我有以下代码:
那是什么意思呢?
现在,我知道
"
现在,让人困惑的是,什么实际上算作异步函数-什么被放入队列中的单独作业中,什么没有。
首先,我们有函数的“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
实际上是一个返回Promise
的函数的语法糖,例如:async function asyncFunc() {
console.log("executing async function");
}
"
是语法糖,它的含义是:
"function asyncFunc() {
return new Promise((resolve) => {
console.log("executing async function");
resolve();
});
}
但是我的观点仍然存在。你传递给Promise的所谓异步函数实际上是同步执行的。嗯,从技术上讲,Promise
对象并不意味着它将被异步执行,但async
关键字却是如此!所以这是完全错误的信息,它让你相信它是异步的,而事实上它证明它不是。
async/await
语法的意图。 - Pointyasync
的方式是将其视为一种“类型”声明,告诉JavaScript“此函数返回一个或多个Promise对象”。然后,解析器可以将该函数的代码构建为生成器函数,每个内部的await
表达式实际上意味着另一个Promise的yield
。 - Pointy