图解 | 4道题带你初步了解浏览器的EventLoop
目录:
0 / 了解进程和线程1 / 浏览器和JSEventLoop事件循环机制2 / 四道题第一题第二题第三题第四题
0 / 了解进程和线程
进程:可以理解为一个程序(浏览器打开一个页面就是开辟一个进程)
线程:程序中具体做事情的那个人
一个进程可以包含很多线程,一个线程同时只能做一件事情
假如,有一天,小虾同学开了个饭店,她家雇了5个服务员:五个线程
每个服务员->每个线程同时只能做一件事情,A在点餐时候,就不能去上菜
同步编程:一件事情一件事情去做,上一件事没有完成,则无法处理下一个事情【单线程】
异步编程:上一件事情还没有处理完,则下一件事情可以继续去处理【多线程、基于单线程的一些EventLoop机制】
浏览器的JS中的异步编程:
① promise
② async/await【generator】
③ requestAnimationFrame
④ 定时器
⑤ ajax【HTTP网络请求】
⑥ 事件绑定
⑦ ……
MutationObserver 浏览器监听 DOM的
1 / 浏览器和JS
JS是单线程的:
① JS中大部分代码都是同步编程
② 可以基于单线程的EventLoop(事件循环机制)实现异步的效果
浏览器是多线程的,打开一个页面后,浏览器可以分配很多线程,同时处理一些事情:
① GUI渲染线程:渲染DOM树、CSSOM树的
② JS引擎(渲染)线程:JS单线程是因为浏览器只会开辟这一个线程,用来执行JS代码
③ HTTP网络请求线程:加载资源文件还是一些数据都是基于HTTP这个线程的
④ 定时器监听线程:监听定时器是否到达时间
⑤ DOM事件监听线程:监听DOM事件的触发
⑥ ……等
△ 图_浏览器线程
请问:
1、JS中有异步编程吗?
2、JS能同时处理多个事情吗?
EventLoop事件循环机制
△ 图1_浏览器的EventLoop
JS中的异步微任务:
① promise
② async/await【generator】
③ requestAnimationFrame
JS中的异步宏任务
① 定时器
② ajax【HTTP网络请求】
③ 事件绑定
setTimeout(()=>{}, 0)
注意点:
① 设置定时器这个是本身是同步的
② 放在EventLoop中的任务是:过多久后,执行回调函数这个事情是异步宏任务
③ 等待时间写0,也不是立即执行,浏览器有最快的反应时间【例如:谷歌在5~6ms,IE在10~17ms,设置0也最少要等待这么多时间】
2 / 四道题
第一题
setTimeout(() => {
console.log(1);
}, 20);
console.log(2);
setTimeout(() => {
console.log(3);
}, 10);
console.log(4);
// console.time('AA');
for (let i = 0; i < 90000000; i++) {
// do something
}
// console.timeEnd('AA'); //=>AA: 79ms 左右
console.log(5);
setTimeout(() => {
console.log(6);
}, 8);
console.log(7);
setTimeout(() => {
console.log(8);
}, 15);
console.log(9);
△ 结果是?
评测程序执行时间:① 大O预估 ② console.time 监测【受系统性能的影响】
△ 图2_第一题
第二题
setTimeout(() => {
console.log(1);
}, 0);
console.log(2);
while (1) {
// do something
}
console.log(3);
setTimeout(() => {
console.log(4);
}, 10);
console.log(5);
△ 结果是?
遇到无限循环时,异步宏任务怎么办?
//----第二题分析
setTimeout(() => {
console.log(1);
}, 0);//=> 异步宏任务①
console.log(2); //=> 输出2
while (1) {//=> 同步任务进入【死循环】,后面代码不会执行了
// do something
}
/*
在 while 处进入死循环后,同步任务不会执行完了
异步的宏任务永远也不会去执行了
*/
console.log(3);
setTimeout(() => {
console.log(4);
}, 10);
console.log(5);
△ 第二题分析:最后输出:2
第三题
setTimeout(function () {
console.log(1);
}, 0);
console.log(2);
console.log(a);
console.log(3);
setTimeout(() => {
console.log(4);
}, 10);
△ 结果是?
遇到报错时,异步宏任务怎么办?
△ 图3_同步任务中报错+异步宏任务
遇到报错后,同步任务就结束了,开始去找异步宏任务了
第四题
setTimeout(function () {
console.log(1);
}, 0);
console.log(2);
try {
console.log(a);
} catch (err) {}
console.log(3);
setTimeout(() => {
console.log(4);
}, 10);
△ 结果是?
遇到同步任务报错,并捕获了异常,同步任务会继续执行到结束,然后再去找异步宏任务
输出:2,3,1,4
- end -
EventLoop事件循环机制,执行顺序:同步任务(执行完后)-->异步微任务(清空后)--> 异步宏任务