返回

浏览器线程、事件循环、宏任务、微任务:一网打尽!

前端

引言:浏览器为何是多线程的?

在回答这个问题之前,我们需要先理解什么是多线程。多线程是指在计算机或操作系统中同时运行多个任务的能力。浏览器需要多线程,主要是出于以下几个原因:

  • 提高浏览器性能:多线程可以提高浏览器性能,因为它允许多个任务同时执行,从而减少任务的等待时间。
  • 提高浏览器稳定性:多线程可以提高浏览器稳定性,因为它可以将不同的任务隔离在不同的线程中,从而防止一个任务的崩溃导致整个浏览器崩溃。
  • 提高浏览器安全性:多线程可以提高浏览器安全性,因为它可以将恶意代码隔离在不同的线程中,从而防止恶意代码对浏览器造成损害。

浏览器线程:JS 线程、浏览器主线程和其他线程

浏览器由多个线程组成,其中最主要的两个线程是 JS 线程和浏览器主线程。

  • JS 线程:JS 线程是专门负责执行 JS 代码的线程。JS 代码是使用 JavaScript 语言编写的,它是一种动态语言,可以对网页进行动态修改。
  • 浏览器主线程:浏览器主线程是负责管理浏览器界面、处理用户输入、发起网络请求等任务的线程。

除了 JS 线程和浏览器主线程之外,浏览器还可能包含其他线程,例如:

  • 网络线程:网络线程是负责处理网络请求的线程。
  • 渲染线程:渲染线程是负责将 HTML、CSS 和 JavaScript 代码转换为可视界面的线程。
  • GPU 线程:GPU 线程是负责处理图形渲染的线程。

事件循环:任务队列与循环

浏览器通过事件循环来管理和执行各种任务。事件循环是一个不断循环的过程,它从任务队列中取出任务并执行它们。任务队列是一个存储任务的队列,当有新的任务产生时,它会将任务添加到任务队列中。当事件循环执行任务时,它会从任务队列中取出任务并执行它们。任务队列是先进先出的,这意味着先添加到队列中的任务将先被执行。

宏任务与微任务:区分与联系

宏任务和微任务都是需要浏览器执行的任务,但它们之间有一些区别。宏任务是指需要较长时间才能执行的任务,例如:

  • 脚本执行:脚本执行是指浏览器执行 JavaScript 代码的任务。
  • 网络请求:网络请求是指浏览器向服务器发送请求并接收响应的任务。
  • 超时函数:超时函数是指在指定时间后执行的函数。

微任务是指需要较短时间就能执行的任务,例如:

  • Promise 回调:Promise 回调是指当 Promise 对象的状态改变时执行的函数。
  • Mutation Observer 回调:Mutation Observer 回调是指当 DOM 树发生变化时执行的函数。
  • setTimeout(callback, 0):setTimeout(callback, 0) 是一个特殊的 setTimeout 函数,它会在当前任务完成之后立即执行回调函数。

宏任务和微任务都存储在任务队列中,但微任务的优先级高于宏任务。这意味着当事件循环执行任务时,它会先执行微任务,然后再执行宏任务。

浏览器是如何处理任务的?

当浏览器收到一个任务时,它会将任务添加到任务队列中。然后,浏览器会开始执行事件循环。在事件循环中,浏览器会从任务队列中取出任务并执行它们。如果任务是一个宏任务,那么浏览器会将其添加到宏任务队列中。如果任务是一个微任务,那么浏览器会将其添加到微任务队列中。

当浏览器执行宏任务时,它会将宏任务队列中的所有任务都执行完。当浏览器执行微任务时,它会将微任务队列中的所有任务都执行完。

总结:浏览器线程、事件循环、宏任务和微任务

浏览器是一个多线程的程序,它通过事件循环来管理和执行各种任务。任务队列是一个存储任务的队列,当有新的任务产生时,它会将任务添加到任务队列中。当事件循环执行任务时,它会从任务队列中取出任务并执行它们。宏任务和微任务都是需要浏览器执行的任务,但微任务的优先级高于宏任务。这意味着当事件循环执行任务时,它会先执行微任务,然后再执行宏任务。