一、JS中的事件(任务)队列 Event Queue
浏览器从服务器获取到代码后,浏览器会开辟一个GUI渲染线程,GUI从上到下开始执行代码。
浏览器是多线程的,包含GUI渲染线程、HTTP网络请求线程(并发数6-7)、事件监听\定时器监听。但JS代码的运行是单线程的
console.log(1);
setTimeout(() => { // 任务1、进入事件队列Event Queue
console.log(2);
}, 1000);
console.log(3);
setTimeout(() => { // 任务2、进入事件队列Event Queue
console.log(4);
}, 0); //=>并不是立即执行,需要等待浏览器的最小反应时间 5~6MS
console.log(5);
for (let i = 0; i < 99999999; i++) {
if (i === 99999998) {
console.log(6);
}
}
console.log(7);
//结果 1 3 5 6 7 4 2
// 循环过程中,任务队列中的任务2已经到达指定的执行时间了,但是此时GUI渲染线程还没有自上而下的执行完,所以需要所有任务队列中的任务(哪怕到达时间)继续候着,直到最后一行执行完,GUI渲染线程会去任务队列中去查找,把到达时间能执行的放到GUI中去执行,如果有多个到达时间,谁先到达先执行谁。代码执行完,GUI空闲下来,继续去任务队列中查找,这种机制叫事件循环机制Event Loop
// 1、GUI渲染中遇到异步操作,都会首先放置在EventQueue中
//2、JS是单线程的,一次只能做一件事情,所以GUI只要没闲下来,就不能干其他的事情(哪怕任务队列中的某些任务到达执行时间了,也不能立即执行,需要等GUI闲下来)
// 3、任务队列中的任务,最后都是拿到GUI线程中处理的,一个任务处理完,才能继续处理下一个任务
// 所以定时器设置的等待时间是最快的执行时间,到达时间后也不一定能执行,需要等GUI闲下来
setTimeout(() => {
console.log(1);
}, 20);
console.log(2);
setTimeout(() => {
console.log(3);
}, 10);
console.log(4);
for (let i = 0; i < 90000000; i++) {
// do soming 79MS
}
console.log(5);
setTimeout(() => {
console.log(6);
}, 8);
console.log(7);
setTimeout(() => {
console.log(8);
}, 15);
console.log(9);
// 输出结果2 4 5 7 9 3 1 6 8
二、微任务和宏任务
Event Queue中分微任务和宏任务
微任务优先级永远高于宏任务,先找微任务,微任务只要还有,则继续按微任务,一直到没有微任务,才去执行宏任务。宏任务的优先级是按照谁先到达执行时间
微任务:promise/async/await
宏任务: 事件绑定、定时器、ajax异步请求
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
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
586

被折叠的 条评论
为什么被折叠?



