小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
问题
今天看到一道题,题目是:
setTimeout(() => {
console.log(1)
},0)
async function timeout () {
const a = await new Promise((resolve,reject) => {
setTimeout(() => {
console.log(2)
resolve(3)
}, 0)
})
console.log(a)
}
await timeout()
console.log(4)
请问打印的顺序是什么?
输出
你可以复制这段代码到控制台上执行,输出的答案是1 2 3 4。
解答
这个题目主要是考察事件循环(Event Loop),微任务和宏任务的知识,我之前也写过文章来分析过,大家感兴趣也可以看看
下面针对这个题目来分析下:
- 第一部分是setTimeout函数,不会立即执行,它属于宏任务,放到宏任务的队列中。
- 第二部分是timeout函数,加了
async前缀,属于微任务,它里面使用了setTimeout函数,于是又把它放到宏任务的队列中。 - 第三部分是在顶层使用了await关键字, timeout函数内部也使用了await,二者配合,所以它后面的代码得等到它的代码执行完才执行。
- 最后输出console.log(4)。
整体的流程是。由于第三部分的await,导致后面的打印4需要等待await函数执行完再执行,然后宏任务队列里面有2个任务,一个是开头的setTimeout,一个是timeout函数的setTimeout。 因为setTimeout函数的延时时间都是0, 所以按照先后顺序执行。 同时timeout函数内部使用了await,所以console.log(a)会在resolve(3)之后才输出,也就是console.log(2)之后。
所以 输出的结果是1 2 3 4。