本文共 2127 字,大约阅读时间需要 7 分钟。
我们可以用浏览器打开很多的网页,关闭其中的任何一个对于其他的网页没有影响,这个大家都明白,因为浏览器是多进程的。说到进程,不得不提到的还有线程,关于他们俩个的区别:
进程是cpu分配资源的最小单位;
线程是进程的最小调度单位;
进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。
对于浏览器,每个tab页面就是一个进程。以多进程形式,允许多个任务同时运行; 以多线程形式,允许单个任务分成不同的部分运行; 提供协调机制,一方面防止进程间和线程间产生冲突,另一方面允许进程之间和线程之间共享资源。
浏览器包括以下进程:
再来张图,我比较喜欢看图:
我们前端需要重点了解的是 浏览器渲染多进程浏览器是多线程,一个页面包含以下线程:
再将以上内容用图片描述一下:
第三部分提到了“队列”,“队列”的另一个伙伴叫做“js执行栈”。 js的引擎机制由“执行栈”和“队列”组成;所有js代码都在栈中执行,队列中的,等待栈中js执行完毕后,再拿到栈中执行。
那哪些js是直接在栈中执行,哪些是需要在队列中等待执行的呢?
解答上面的这个问题前,需要先了解 “宏任务” 和 “微任务”。
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。同样,宏任务队列有很多个,也是按照先入先出的顺序执行。
再来张图:
参考文章:
本文作者:Liz栗子
本文来源: 如需转载请联系原作者