You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Per its source field, each task is defined as coming from a specific task source. For each event loop, every task source must be associated with a specific task queue.
理解 Event loops
在本章以 whatwg 中的 HTML Standard 规定为标准(w3c 已经和 whatwg 签署协议,达成合作)。
定义
定义中只是表明了 event loop 的作用:协调事件、用户交互等,也就是在 JavaScript 的单线程中,异步处理回调,保证不会阻塞。实际浏览器是多线程,采用了多线程保证不阻塞。比如我们平常使用的 setTimeout 函数使用了定时器触发线程。关于浏览器以后有机会在介绍。
在 ECMAScript 中有 Jobs and Job Queues 和 RunJobs ( ) ,这里规定是的是 JavaScript 引擎(比如说 chrome 中的 V8 引擎)独立运行时,需要用到这里的规定来处理 Promise 异步问题。这个规定是处理 JavaScript 自己函数的异步问题。而 event loop 是属于 JavaScript Runtime的,是需要嵌入到宿主环境的(比如浏览器和 Nodejs),在宿主环境中,不只是 JavaScript 自己有异步,还有环境中其他异步。这些异步就是定义中说的事件、用户交互、脚本、UI渲染、网络请求。所以在 HTML Standard 中的 8.1.3.7 Integration with the JavaScript job queue 中明确提到在用户代理中,使用 HTML 文档中的 Event loops,而 ECMAScript 中的 Promise 集成到 event loop 中。
**注:**Nodejs 中的 event loop 单独介绍。
任务队列 task
task queue(macrotask)
一个 event loop 有一个或多个 task queues。这里的 task 就是 macrotask,在规定中没有明确提出 macrotask ,task queue 中存放不同任务源的 task。常见的任务源:
对于 task :
来自相同任务源的 task 放在同一 task queue 中,不同任务源的 task 放在不同 task queue 中。
同一 task queue 中的 task 顺序执行,不过 task queue 中的 task 浏览器(宿主环境)根据实际情况进行调度。
一般来说,鼠标、键盘 task queue 中的 task 优先于其他 task queue 中的 task,目的是保证用户体验。
microtask queue
一个 event loop 只有一个 microtask queue。
microtask queue 的任务源规范中没有明确规定,一般就是:
event loop 处理过程
在 HTML 规范中 8.1.4.3 Processing model 有明确规定,这里做一个概括:
一般把执行全局 JavaScript 当做一个 task。
microtask checkpoint
在 event loop 处理过程中,对于 microtask 有一个很重要的步骤就是 microtask checkpoint:
performing a microtask checkpoint 为 false 才执行 microtask checkpoint。如果为 true ,直接返回。
如果 microtask queue 不为空,选出 oldestMicrotask 执行,在执行 oldestMicrotask 有可能触发 Calling scripts 的清理阶段(clean up after running script),在清理阶段也会执行 microtask 检查任务。所以一开始需要检查 performing a microtask checkpoint 状态。
microtask 执行时机
在 event loop 中,microtask 是在一个 task 执行完之后在执行,但是在 HTML 文档中,有很多处调用 microtask checkpoint:
执行 microtask 前提是:执行栈必须为空,且没有正在运行的执行上下文。
有一个很好的例子:
html 代码
JavaScript 代码
第一种情况是:点击 id 为 inner 的区域,结果如下:
第二种情况是:添加 inner.click(),通过 JavaScript 代码触发回调,结果如下:
两种情况有明显差别,根本原因就是:两种情况下,执行栈情况不同,第二种情况 inner.click 在回调函数执行完(回调函数中的异步没有执行)之前,一直存在执行栈中,这种情况下是不会检查 microtask 队列的。
详细解释可以看这里。
Update the rendering (更新渲染)
这里只介绍 event loop 中 Update the rendering 的内容,不会涉及浏览器具体怎么更新渲染。
在 event loop 处理过程中,在最后会进行 Update the rendering ,但并不是每一次 event loop 都会执行 Update the rendering,浏览器会做一个综合判断,更新渲染是否获利,保证 60Hz 的刷新率等。
Update the rendering 总体来说有两个大的步骤:判断是否更新、更新时处理的各种事件。
在更新渲染阶段处理的事件如下:
参考资料
HTML 文档 event loops
深入理解 JavaScript Event Loop
跟着 Event loop 规范理解浏览器中的异步机制
JavaScript 中的 task queues
深入探究 eventloop 与浏览器渲染的时序问题
从event loop规范探究javaScript异步及浏览器更新渲染时机
ECMAScript 的 Job Queues 和 Event loop 有什么关系?
浏览器渲染详细过程:重绘、重排和 composite 只是冰山一角
The text was updated successfully, but these errors were encountered: