Event Loop:事件循环
跳到导航
跳到搜索
关于
在 MDN 上看到 JavaScript 的《并发模型与事件循环》一节,但由于该页面内容过少,实在不变学习。 而网络上搜到的内容大同小异,互相又有不小出入,难以拿捏。 众所周知,JavaScript 是没有所谓源代码的“源代码”,所以这部分内容只能在“规范”文件[1]了。
以下内容参照《HTML Standard》、MDN、与网络内容整理。
浏览器进程/线程模型
浏览器进程架构有两种方案:单进程多线程和多进程(通过IPC传递消息)。
- 单进程多线程:顾名思义,浏览器在同一个进程运行所有功能模块(包括篇:网络、插件、JavaScript 运行环境、渲染引擎和页面等)
- 其缺点很明显:
- 不稳定:任一线程错误,将导致整个进程崩溃
- 不流畅:同一时刻只有一个浏览器模块可用
- 不安全:各线程共享进程数据,更容易导致攻击
- 高占用:进程关闭之前,不会回收由线程占用的资源
- (其实早在 2007 年之前,市面上浏览器都是单进程的)
多进程型
现代浏览器多从用多进程模型,但各家实现细节各有差异。 (以 Chrome 为例)
浏览器主要进程,包括:
- 浏览器进程(Browser Process):(主进程)控制应用程序的“chrome”部分,包括地址栏、书签、后退和前进按钮。还处理网络浏览器中不可见的特权部分,如网络请求和文件访问。
- 渲染进程(Renderer Process):(内核进程)控制显示网站的选项卡内的任何内容。
GUI 渲染线程 JavaScript引擎线程 事件触发线程 定时触发器线程 异步http请求线程
- GPU进程(GPU Process):处理应用程序的 GPU 任务,并将它们绘制在同一个表面上。
- 插件进程(Plugin Process):控制网站使用的任何插件。
- 每启用一个插件,则新增一个进程
macrotask 与 microtask
JavaScript中,“任务”被分为两种:“任务”(Task,也叫:宏任务,MacroTask)与“微任务”(MicroTask)。
- 宏任务(macrotask):
- 微任务(microtask):
运行时
与 Java 的运行时概念类似,JavaScript 也有其运行时。
事件循环
要协调事件、用户交互、脚本、渲染、网络等,用户代理必须使用本节中描述的事件循环。每个代理都有一个关联的事件循环,该循环对该代理是唯一的。
当宏任务和微任务都处于 任务队列(Task Queue) 中时,微任务的优先级大于宏任务,即先将微任务执行完,再执行宏任务; 这是理解上优点小偏差