vlambda博客
学习文章列表

​图解 | 4道题带你初步了解浏览器的EventLoop

▲ 点击上方蓝字关注我 ▲
This browser does not support music or audio playback. Please play it in Weixin or another browser.


目录:
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事件的触发

⑥ ……等


​图解 | 4道题带你初步了解浏览器的EventLoop

△ 图_浏览器线程


请问

1、JS中有异步编程吗?

2、JS能同时处理多个事情吗?


EventLoop事件循环机制

​图解 | 4道题带你初步了解浏览器的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 监测【受系统性能的影响】



​图解 | 4道题带你初步了解浏览器的EventLoop

△ 图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);

△ 结果是?


遇到报错时,异步宏任务怎么办?

​图解 | 4道题带你初步了解浏览器的EventLoop

△ 图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事件循环机制,执行顺序:同步任务(执行完后)-->异步微任务(清空后)--> 异步宏任务