我试图弄清楚异步代码如何在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
关键字却可以!因此,它是完全错误的信息,它使您相信它是异步的,而事实证明并非如此。
答案 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");