浏览器中的事件循环
-
JS是单线程的,所以有些耗时操作会给浏览器的其他线程执行,执行好后放回任务队列中,JS代码执行完后再执行任务队列中的任务
-
任务队列分为宏任务队列和微任务队列
- 宏任务:ajax setTimeout setInterval DomListener等
- 微任务:Promise.then()的回调 queueMicrotask()
- 执行宏任务队列里的任务前要保证微任务队列为空
题目:
async function async1 () {
console.log('async1 start')
await async2();
console.log('async1 end')
}
async function async2 () {
console.log('async2')
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout')
}, 0)
async1();
new Promise (function (resolve) {
console.log('promise1')
resolve();
}).then (function () {
console.log('promise2')
})
console.log('script end')
解析
首先执行 script start,然后执行setTimeout()回调函数被放进了宏任务队列中(没设置事件默认为0,如果设置了事件需要等到相应的时间后再加入到宏任务队列中),接下在执行async1函数,log('async1 start'),接着执行async2函数 log('async2') ,async2执行完成后返回一个promise.resolve(undefined),回到async1 注意await 后的函数将会被放在返回的promise.then中执行,所以console.log('async1 end')被加入到微任务队列中,async1执行完,然后执行 new Promise(),首先会log('promise1'),调用resolve()后进入then,then中回调函数被加入到微任务队列,再执行script end 现在微任务队列中有两个任务 宏任务队列有一个任务,依次执行 async1 end 、promise2 、setTimeout