JavaScript的事件循环机制

事件循环机制的核心是一个事件循环线程,它持续运行并监听事件队列。当有事件需要处理时,事件循环会将事件从队列中取出并执行相应的回调函数

Why-为什么需要事件循环机制

JavaScript是一种单线程的编程语言,意味着它一次只能执行一个任务。如果在执行一个耗时的操作时,如网络请求或计算密集型任务,如果JavaScript采用同步的方式执行,那么整个页面或应用程序将会被阻塞,用户无法进行其他操作,直到该任务完成。这会导致用户体验不佳,页面或应用程序的响应性能下降。

为了解决这个问题,JavaScript引入了事件循环机制。事件循环机制允许JavaScript在执行异步任务时,不必等待任务完成,而是继续执行后续的代码。它通过将异步任务放入任务队列中,并在主线程空闲时执行相应的回调函数,实现了非阻塞的异步执行。

具体来说,事件循环机制的好处包括:

  1. 增强用户体验:通过使用事件循环机制,可以确保页面或应用程序的响应性能更高,用户可以在进行耗时操作时继续进行其他操作。
  2. 提高性能:通过将耗时的任务放入异步队列中,JavaScript可以继续执行其他任务,充分利用计算资源,提高整体性能。
  3. 处理事件和交互:事件循环机制使得JavaScript能够处理用户交互、事件监听和响应,例如点击事件、键盘事件和鼠标事件等。
  4. 支持异步操作:JavaScript中有许多常见的异步操作,如网络请求、文件读写和定时器等。事件循环机制使得这些异步操作可以以非阻塞的方式执行,提高代码的效率和可维护性。

What-事件循环究竟是什么

在 JavaScript 中,异步任务可以分为宏任务微任务

宏任务一般包括了以下几种:

  • setTimeoutsetInterval
  • I/O 操作,如 Ajax文件读取
  • UI渲染

微任务一般包括以下几种:

  • Promise.then()catch()方法
  • process.nextTick()
  • MutationObserver()方法

JavaScript 中的事件循环机制由下面四个部分组成:

  1. 调用堆栈(Call Stack)
    调用堆栈记录了 JavaScript 代码的执行顺序。当代码开始执行时,会被顺序推入调用堆栈(Call Stack),当函数执行完毕后,会从堆栈中弹出。由于 JavaScript 是单线程的,所以在调用堆栈中只能有一个任务在执行。在执行宏任务的过程中,如果遇到了微任务会将其加入微任务队列;

  2. 宏任务队列(Task Queue)
    宏任务队列可以理解为存放宏任务的一个队列。当遇到宏任务时,它会被顺序加入到宏任务队列中。宏任务一般是异步任务,包括 setTimeoutsetIntervalI/O 操作等。只有当前的宏任务执行完毕之后,才会执行下一个宏任务。

  3. 微任务队列(Microtask Queue)
    微任务队列也可以理解为存放微任务的一个队列。当遇到微任务时,它会被顺序加入到微任务队列中。在每个宏任务执行结束后,会检查微任务队列是否为空。如果不为空,就会执行微任务队列中的所有任务,直到微任务队列为空。

  4. 渲染队列(Render Queue)
    渲染队列主要是用于浏览器中的渲染,保存了在执行宏任务期间发生的所有页面渲染操作,例如修改了 DOM 树中的节点内容。当宏任务执行完毕后,JavaScript引擎会检查是否需要更新页面,如果需要,则进行渲染,否则跳过这个步骤。

How-事件循环机制是如何执行的

事件循环机制的执行过程可以分为以下几个步骤:

  1. 执行同步代码:JavaScript首先会执行当前的同步代码,即按照顺序执行代码块中的语句,直到遇到异步任务或事件。

  2. 将异步任务放入任务队列:当遇到异步任务时,JavaScript会将其放入任务队列中,而不是立即执行。异步任务可以是定时器(setTimeoutsetInterval)、网络请求(AjaxFetch)、Promise等。这些异步任务会在特定的条件满足后被触发执行。

  3. 监听事件队列:事件循环线程会持续监听事件队列,以检查是否有待处理的事件或异步任务。事件队列中存储了待处理的事件和异步任务。

  4. 执行事件处理或异步任务:当事件循环线程发现事件队列中有待处理的事件时,它会取出事件,并执行相应的事件处理函数。对于异步任务,当主线程空闲时,事件循环线程会从任务队列中取出任务,并执行相应的回调函数。

  5. 重复执行:一旦执行完一个事件处理或异步任务,事件循环线程会再次检查事件队列,看是否还有待处理的事件。如果有,它会继续执行下一个事件处理或异步任务。这个过程会一直重复,直到事件队列和任务队列都为空。

需要注意的是,事件循环机制是单线程的,意味着同一时间只能执行一个任务。当事件循环线程执行事件处理或异步任务时,其他任务需要等待。这也是为什么长时间运行的任务可能会阻塞主线程,导致页面或应用程序的响应性能下降。

Got-能从中收益什么

通过事件循环机制,JavaScript能够以非阻塞的方式处理异步任务和事件,提高代码的执行效率和用户体验。了解事件循环机制的执行过程对于编写高效的异步代码非常重要,因为它可以帮助你理解代码执行的顺序和如何处理异步操作。


JavaScript的事件循环机制
https://mqpeng.github.io/2021/08/04/event-loop/
作者
Joker Spice
发布于
2021年8月4日
许可协议