将本身读到的比较好的文章分享出来,你们互相学习,各位大佬有好的文章也能够留个连接互相学习,万分感谢!
关于线程与进程的关系能够用下面的图进行说明:ios
1:n
的关系。而官方的说法是:git
CPU
资源分配的最小单位。CPU
调度的最小单位。从更直观的例子来看,能够打开任务管理器查看,第一个 tab
即是进程列表,每个进程占有的 CPU
资源和内存资源的比例很直观的展现出来。github
初学计算机语言的时候,不管是 C、C++
仍是 JAVA
,都是支持多线程,恰恰 JavaScript
是单线程,不支持多线程,这也跟 JavaScript
的做用有关,都知道 JavaScript
是主要运行在浏览器的脚本语言,最终操做的是页面的 DOM
结构,当两个 JavaScript
脚本同时修改页面的同一个 DOM
节点时,浏览器该执行哪一个呢?因此当时设计 JavaScript
时,便要求当前修改操做完成后方可进行下一步修改操做。ajax
一样咱们打开浏览器的任务管理器,如下图为例:浏览器
浏览器的每个 tab
页都是一个进程,有对应的内存占用空间、 CPU
使用量以及进程ID。 新打开一个 tab
页时,都会新建一个进程,因此就有一个 tab
页对应一个进程的说法,可是这种说法又是错误的,由于浏览器有本身的优化机制,当咱们打开多个空白的 tab
页时,浏览器会将这多个空白页的进程合并为一个,从而减小了进程的数量个数。多线程
浏览器内核中有多个进程在同步工做,今天涉及到的浏览器的进程主要包括如下进程:异步
主进程,主要负责页面管理以及管理其余进程的建立和销毁等,常驻的线程有:函数
- GUI渲染线程
- JS引擎线程
- 事件触发线程
- 定时器触发线程
- HTTP请求线程
GUI渲染线程oop
- 主要负责页面的渲染,解析HTML、CSS,构建DOM树,布局和绘制等。
- 当界面须要重绘或者因为某种操做引起回流时,将执行该线程。
- 该线程与JS引擎线程互斥,当执行JS引擎线程时,GUI渲染会被挂起,当任务队列空闲时,JS引擎才会去执行GUI渲染。
JS引擎线程布局
- 该线程固然是主要负责处理
JavaScript
脚本,执行代码。- 也是主要负责执行准备好待执行的事件,即定时器计数结束,或者异步请求成功并正确返回时,将依次进入任务队列,等待
JS引擎线程
的执行。- 固然,该线程与
GUI渲染线程
互斥,当JS引擎线程
执行JavaScript
脚本时间过长,将致使页面渲染的阻塞。事件触发线程
- 主要负责将准备好的事件交给
JS引擎线程
执行。- 好比
setTimeout
定时器计数结束,ajax
等异步请求成功并触发回调函数,或者用户触发点击事件时,该线程会将整装待发的事件依次加入到任务队列的队尾,等待JS引擎线程
的执行。定时器触发线程
- 顾名思义,负责执行异步定时器一类的函数的线程,如:
setTimeout,setInterval
。- 主线程依次执行代码时,遇到定时器,会将定时器交给该线程处理,当计数完毕后,事件触发线程会将计数完毕后的事件加入到任务队列的尾部,等待JS引擎线程执行。
HTTP请求线程
- 顾名思义,负责执行异步请求一类的函数的线程,如:
Promise,anxios,ajax
等。- 主线程依次执行代码时,遇到异步请求,会将函数交给该线程处理,当监听到状态码变动,若是有回调函数,事件触发线程会将回调函数加入到任务队列的尾部,等待JS引擎线程执行。
多个线程之间配合工做,各司其职。
浏览器渲染进程(浏览器内核),主要负责页面的渲染、JS执行以及事件的循环。
console.log()
打印一条日志、声明一个变量或者执行一次加法操做等。常见的异步操做:
下图给出了同步任务与异步任务的执行流程:
那么任务究竟是如何入栈和出栈的呢?能够用一小段代码进行解释。
如下面的代码为例:
console.log(1); function fn1(){ console.log(2); } function fn2(){ console.log(3); fn1(); } setTimeout(function(){ console.log(4); }, 2000); fn2(); console.log(5);
因此上面代码运行的结果为:1,3,2,5,4。
异步任务分为宏任务和微任务,宏任务队列能够有多个,微任务队列只有一个。
宏任务和微任务的执行方式在浏览器和 Node
中有差别。
script
(全局任务),setTimeout
,setInterval
,setImmediate
,I/O
,UI rendering
process.nextTick
,Promise.then()
,Object.observe
,MutationObserver
在微任务中 process.nextTick 优先级高于Promise
当一个异步任务入栈时,主线程判断该任务为异步任务,并把该任务交给异步处理模块处理,当异步处理模块处理完打到触发条件时,根据任务的类型,将回调函数压入任务队列。
因此上图的任务队列能够继续细化一下:
那么当栈为空时,宏任务和微任务的执行机制又是什么呢?
到这里,除了上面的问题,咱们已经把事件循环的最基本的处理方式搞清楚了,但具体到异步任务中的宏任务和微任务,尚未弄明白。咱们能够先顺一遍执行机制:
script
开始,任务依次进入栈中,被主线程执行,执行完后出栈。到这问题就来了,当异步任务进入栈执行时,是宏任务仍是微任务呢?
script
,而全局任务属于宏任务,因此当栈为空,同步任务任务执行完毕时,会先执行微任务队列里的任务。回到最开始的那段代码,如今咱们能够一步一步的看一下执行顺序。
console.log(1); setTimeout(function(){ console.log(2); }, 0); setTimeout(function(){ console.log(3) },2000) console.log(4);
1
,setTimeout
,交给异步处理模块,咱们暂且先记为 setTimeout1
,setTimeout
,交给异步处理模块,咱们暂且先记为 setTimeout2
,4
,setTimeout1
的回调函数,由于定时器的等待时间为 0
秒,因此会直接输出 2
,可是 W3C
在 HTML
标准中规定,规定要求 setTimeout
中低于 4ms
的时间间隔算为 4ms
,setTimeout1
执行完时, setTimeout2
的等待时间并未结束,因此在 2秒
后打印日志 3
,实际上并未等待2秒。下面咱们能够再看一个实例:
setTimeout(function(){ console.log(1); Promise.resolve().then(function(){ console.log(2) }) },0) setTimeout(function(){ console.log(3) },0) Promise.resolve().then(function(){ console.log(4) }); console.log(5)
当代码中遇到了异步请求的事件,又该如何执行,根据上面总结的执行机制,又该获得什么样的结果?
第一轮循环
setTimeout
,交给异步处理模块,咱们暂且先记为 setTimeout1
,因为等待时间为 0
,直接加入宏任务队列。setTimeout
,交给异步处理模块,咱们暂且先记为 setTimeout2
,一样直接加入宏任务队列。then()
,加入微任务队列。5
。第一轮循环结束后,能够画出下图:
第二轮循环
then()
方法,输出 4
,此时微任务队列为空。setTimeout1
。1
,又遇到微任务 then()
,加入微任务队列。第二轮循环结束。第三轮循环
then()
方法,输出 2
,此时微任务队列为空。setTimeout2
。3
。第三轮循环结束,执行完毕。最后咱们是咱们的boss,欢迎你们在评论区留言写出本身心中的那个正确答案。
console.log(1); setTimeout(function(){ console.log(2); new Promise(function(resolve, reject){ console.log(3); resolve(); }).then(function(){ console.log(4); }) }) new Promise(function(resolve, reject){ console.log(5); resolve(); }).then(function(){ console.log(6); }) setTimeout(function(){ console.log(7) }) setTimeout(function(){ console.log(8); new Promise(function(resolve, reject){ console.log(9); resolve(); }).then(function(){ console.log(10); }) }) new Promise(function(resolve){ console.log(11); resolve(); }).then(function(){ console.log(12) }) console.log(13)
github地址:https://github.com/ABCDdouyaer/a_article_per_day/tree/master/0001
原文连接:https://mp.weixin.qq.com/s/9_hZX_xWSr3Gd1X_2_WOsA