1、浏览器执行JS代码的机制:
/**
(1)、首先,浏览器是多线程的,但是JS是单线程的;
(2)、浏览器执行JS代码时,会分配出一个主线程执行JS代码,当JS代码中出现异步代码时,
浏览器会将异步代码加入 等待任务队列(Event Queue)中,当主线程把要执行的代码执行
完毕后,会进入到 等待任务队列中,将异步代码按照一定的规则执行;
*/
2、等待任务队列(Event Queue):
/**
(1)等待任务队列是指主线程执行代码时,遇到的异步执行代码将异步代码放置的地方,
等待主线程空闲时再执行这个异步代码;相当于一个堆内存,存放等待执行的代码;
等待任务队列分为:宏任务队列和微任务队列;
(2)宏任务队列(macro task queue):定时器、事件绑定、Ajax;
(3)微任务队列(micro task queue):Promise、Async/await......;
*/
3、简单例子(未区分宏任务、微任务):
setTimeout(() => {
console.log(1)
}, 50);
setTimeout(() => {
console.log(2)
}, 0);
console.time('FOR');
for (let i = 0; i < 100000000; i++) {
}
console.timeEnd('FOR');
setTimeout(() => {
console.log(3)
}, 20);
console.log(4);
/**
这个执行结果有两种情况:
(1)如果for循环耗时小于50ms和20ms定时器的差值,那么当for循环执行完毕后,将20ms定时器
推入到Event Queue后,还是20ms定时器先到达执行时间;执行结果就是:4,2,3,1;
(2)如果for循环耗时大于50ms和20ms定时器的差值,那么当for循环执行完毕后,50ms定时器的
剩余时间小于20ms,此时20ms定时器才刚刚推进Event Queue中,刚开始计时,所以执行结果是:
4,2,1,3
*/
Event Loop.png
4、经典面试题(区分宏任务、微任务):
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');
宏任务、微任务.png
网友评论