JavaScript运行机制总结

JavaScript运行机制总结


文章摘抄总结至 此处,只用于个人学习啊啊啊啊啊啊,侵权删


从浏览器说起


1.浏览器是多进程的

2.浏览器的每一个tab页面相当与一个独立的浏览器进程,某些情况tab页面可能被浏览器合并

3.浏览器包括的进程与多进程优点如下图所示:

图1-1 浏览器的多线程及其优点

渲染进程(Renderer进程)


1.  页面的渲染,JS的执行,事件的循环,都要集中在 渲染进程 

2.  渲染进程是多线程的

3.  渲染进程的常驻线程及其作用如下图所示:

图1-2 渲染进程的常驻线程及其作用

浏览器主进程(Browser进程)与渲染进程的通信


如下图所示:

图1-3 浏览器主进程(Browser进程)与渲染进程通信流程

涉及到的进程:

图1-4 浏览器渲染时进程之间的通信

渲染进程中的线程


1. GUI渲染线程与JS引擎线程互斥

图1-2 渲染进程的常驻线程及其作用  中提到 GUI渲染线程与JS引擎线程互斥,因为JavaScript是可以操作DOM的元素的(DOM提供了接口),同时操作DOM和渲染页面是不大现实的,因为数据不一致。故在JS引擎执行时,GUI渲染线程是被挂起的,待JS引擎空闲时恢复。故这一机制会有如下问题。

2. JS会阻塞页面的加载

由于 GUI渲染线程与JS引擎线程互斥 ,JS引擎在巨量运算时,GUI渲染线程只能干等,在用户上看就有卡顿的感觉,页面渲染不连贯。

3. Web Worker

创建Worker时,JS引擎向浏览器申请开一个子线程(子线程是浏览器开的,完全受主线程控制,而且不能操作DOM);JS引擎线程与worker线程间通过特定的方式通信(postMessage API,需要通过序列化对象来与线程交互特定的数据)。

综上,Web Worker是另开一个线程,用于解决计算量大的问题,而JS引擎依旧是单线程

另外 SharedWorker 与 WebWorker 本质上就是进程和线程的区别,haredWorker由独立的进程管理,WebWorker只是属于render进程下的一个线程

浏览器渲染流程


浏览器在渲染过程中,主要涉及到 渲染进程的GUI渲染线程。参考下面图片:

图1-5 浏览器渲染页面流程图

JS运行机制与Event Loop


1. JS分为同步任务和异步任务

2. 同步任务都在 主线程(JS引擎线程) 上执行,形成一个 执行栈

3. 主线程之外,事件触发线程 管理着一个任务队列,只要异步任务(如定时器触发线程计时完毕等)有了运行结果,就在任务队列之中放置一个事件。(这里的回调函数还涉及到 定时触发器线程 和 异步http请求线程 的回调函数

4. 一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行

如下图:

图1-6 JS事件循环图


图1-7 JS事件循环图2

故JS的事件循环(Event Loop)过程是:

1. 主线程(JS引擎线程)运行时会产生执行栈栈中的代码调用某些api(上图所示)时,当满足触发条件后,(如ajax请求完毕有回调函数)它们会在事件队列中添加各种事件

2. 当 栈中的代码执行完毕,就会读取(队列头部开始)事件队列中的事件,放入执行栈中,去执行那些回调

3. 重复1,2

综上,JS在运行的时候主要涉及到 渲染进程的两个线程——JS引擎线程 和 事件触发线程,另外,在执行代码时,可能会触发到 定时器触发线程 以及 异步http请求线程。

事件循环的另一个角度:macrotask与microtask


原因:在ES6之后,Promise里有了一个新的概念:microtask

如此一来,JS中分为两种任务类型:macrotask和microtask,在ECMAScript中,microtask称为jobs,macrotask可称为task。

macrotask: 

1. macrotask(又称之为宏任务),可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)

2. 浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染 (task->渲染->task->...)

microtask: 

1. microtask(又称为微任务),可以理解是在当前 task 执行结束后立即执行的任务

2. 也就是说,在当前task任务后,下一个task之前,在渲染之前执行

3. 在某一个macrotask(宏任务)执行完后,就会将在它执行期间产生的所有microtask(微任务)都执行完毕(在渲染前)

4. 微任务有微任务队列(Job Queues)

宏任务与微任务分类:

macrotask:主代码块,setTimeout,setInterval,setImmediate,MessageChannel (优先级先于setTimeout)等(可以看到,事件队列中的每一个事件都是一个macrotask)

microtask:Promise,process.nextTick,MutationObserver(优先级最小)等

另外,setImmediate是有规定:在下一次Event Loop(宏任务)时触发(所以它是属于优先级较高的宏任务), (Node.js文档中称,setImmediate指定的回调函数,总是排在setTimeout前面

综上,一次的Event Loop(事件循环) 的运行机制就是以下几个步骤:

1. 执行一个宏任务(第一次肯定是栈中的代码块,没有就从事件队列中获取)

2. 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中

3. 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(当没有优先级时依次执行)

4. 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染

5. 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)

如下图所示:

图1-8 事件循环之宏任务与微任务图

注:有一些浏览器执行结果不一样(因为它们可能把microtask当成macrotask来执行了), 但是为了简单,这里不描述一些不标准的浏览器下的场景(但记住,有些浏览器可能并不标准)。另外,Promise的polyfill与官方版本的实现不同。polyfill,一般都是通过setTimeout模拟的,所以是macrotask形式。

参考文章:

1. http://www.dailichun.com/2018/01/21/js_singlethread_eventloop.html

2. https://segmentfault.com/a/1190000017204460

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355