javascript单线程,浏览器多线程和任务队列

入门前端时仅仅知道js单线程,了解浏览器的事件循环,常常分不清js引擎在事件 循环中扮演什么样的角色,甚至一度产生错误理解:js引擎的工作就是事件循环的全部。

随着认识的拓宽和加深,了解了任务队列机制(macrotask队列和microtask队列)、浏览器事件触发和UI渲染后,明白了事件循环机制如下图所示:

事件循环包含两个线程,js主线程(就是我们常说的js单线程引擎)和事件触发线程。事件触发线程负责将待处理事件添加到任务队列末尾等待js主线程即js引擎处理,这些事件可来自JavaScript引擎当前执行的代码块如setTimeout、也可来自浏览器内核的其他线程如鼠标点击、Ajax异步请求等。js主线程基于事件驱动单线程执行,一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JavaScript线程在运行JavaScript程序。

UI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(Reflow)时,该线程就会执行。注意,GUI渲染线程与JavaScript引擎互斥,当JavaScript引擎执行时GUI线程会被挂起,UI更新会被保存在一个队列中等到JavaScript引擎空闲时立即被执行。

综上,浏览器至少有最基本的三个线程组成——js主线程、事件触发线程和UI渲染线程。

ES6以来,任务队列又包括macrotask队列和microtask队列,macrotask包括script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、setImmediate(Node.js 环境);microtask包括Promise、MutaionObserver、process.nextTick(Node.js 环境)。先执行一个主任务,然后执行所有微任务,执行完后如果event loop还是检测到微任务(比如一个微任务内又创建了一个微任务),仍然执行微任务,检测出没有微任务,我们就执行一个宏任务,依此循环。

发布了71 篇原创文章 · 获赞 31 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/m0_37828249/article/details/94838935