一、线程和进程
我们可以用浏览器打开很多的网页,关闭其中的任何一个对于其他的网页没有影响,这个大家都明白,因为浏览器是多进程的。说到进程,不得不提到的还有线程,关于他们俩个的区别:
进程是cpu分配资源的最小单位;
线程是进程的最小调度单位;
进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。
对于浏览器,每个tab页面就是一个进程。以多进程形式,允许多个任务同时运行; 以多线程形式,允许单个任务分成不同的部分运行; 提供协调机制,一方面防止进程间和线程间产生冲突,另一方面允许进程之间和线程之间共享资源。
二、浏览器多进程
浏览器包括以下进程:
- 主进程:负责协调和主控,只有一个;
- 第三方插件:每个类型一个进程;
- GPU进程:3D绘制;
- render渲染进程:浏览器渲染进程,每个tab一个进程互不影响;
再来张图,我比较喜欢看图:
我们前端需要重点了解的是 浏览器渲染多进程三、浏览器多线程
浏览器是多线程,一个页面包含以下线程:
- GUI线程:负责浏览器页面渲染,解析html,css构建,Dom树子和renderObject对象,布局和绘制;
- js引擎线程:负责执行js脚本,先渲染页面后执行js;
- 事件触发线程:事件触发时,负责把事件放入队列,等待执行;
- 定时器线程:将settimeout和setinterval执行函数再触发时放入队列等待执行;
- http请求线程:监听请求状态变更,将相应函数放入队列,等待执行;
再将以上内容用图片描述一下:
四、浏览器事件循环
第三部分提到了“队列”,“队列”的另一个伙伴叫做“js执行栈”。 js的引擎机制由“执行栈”和“队列”组成;所有js代码都在栈中执行,队列中的,等待栈中js执行完毕后,再拿到栈中执行。
那哪些js是直接在栈中执行,哪些是需要在队列中等待执行的呢?
解答上面的这个问题前,需要先了解 “宏任务” 和 “微任务”。
- 宏任务:script(整体代码),setTimeout,setInterval,ie支持的setImmediate,MessageChannel,
- 微任务:es6的Promise的then,Object.observe(已废弃),MutationObserver(html5新特性)
js在执行过程中先执行宏任务,有以下的情况:
- 如果在执行过程中产生了微任务:那么,等本轮的宏任务完成后立刻去执行微任务。
- 在执行过程中产生宏任务:等本轮的宏任务完成后立刻去执行宏任务。
- 在执行过程中产生宏任务和微任务:等本轮的宏任务完成后,先去清空微任务列表,再去执行下一个宏任务。(在执行下个宏任务过程中,任然按照以上分析的情况来处理)
来段代码解释一下上面的描述:
console.log("我是开始");
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('我是结束');
复制代码
以上的打印结果顺序:
我是开始 我是结束 promise1 promise2 setTimeout
分析一下:
console.log("我是开始"); //主程序代码(宏任务1)
setTimeout(function() { //产生了一个新的宏任务2——————放入宏任务队列
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() { //产生了微任务1——————放入微任务队列
console.log('promise1');
}).then(function() { //产生了微任务2——————放入微任务队列
console.log('promise2');
});
console.log('我是结束'); //主程序代码(宏任务1)
复制代码
按照以上的注释,先执行宏任务1 ,将本轮宏任务全部执行后,打印出“我是开始”,“我是结束”
刚才也讲过,每执行完一个宏任务后,如果有微任务就去清空微任务队列,现在看下,微任务列表现在有两个微任务,那么就将 promise1 promise2 打印出来。多个微任务是按照先入先出的顺序执行。
清空了微任务列表,再看看是否还有宏任务,发现宏任务列表还有个setTimeout,然后就把它执行以下,打印出结果 setTimeout。同样,宏任务队列有很多个,也是按照先入先出的顺序执行。
再来张图:
以上,就是我对浏览器事件循环的理解,欢迎大家批评指正。参考文章:
- 来自Google开发者Jake:jakearchibald.com/2015/tasks-…
- 来自微信公众号“前端早读课的文章”:mp.weixin.qq.com/s?__biz=MjM…
本文作者:Liz栗子
本文来源:掘金 如需转载请联系原作者