JavaScript的事件循环机制
事件循环机制的核心是一个事件循环线程,它持续运行并监听事件队列。当有事件需要处理时,事件循环会将事件从队列中取出并执行相应的回调函数
Why-为什么需要事件循环机制
JavaScript
是一种单线程的编程语言,意味着它一次只能执行一个任务。如果在执行一个耗时的操作时,如网络请求或计算密集型任务,如果JavaScript
采用同步的方式执行,那么整个页面或应用程序将会被阻塞,用户无法进行其他操作,直到该任务完成。这会导致用户体验不佳,页面或应用程序的响应性能下降。
为了解决这个问题,JavaScript
引入了事件循环机制。事件循环机制允许JavaScript
在执行异步任务时,不必等待任务完成,而是继续执行后续的代码。它通过将异步任务放入任务队列中,并在主线程空闲时执行相应的回调函数,实现了非阻塞的异步执行。
具体来说,事件循环机制的好处包括:
- 增强用户体验:通过使用事件循环机制,可以确保页面或应用程序的响应性能更高,用户可以在进行耗时操作时继续进行其他操作。
- 提高性能:通过将耗时的任务放入异步队列中,
JavaScript
可以继续执行其他任务,充分利用计算资源,提高整体性能。 - 处理事件和交互:事件循环机制使得
JavaScript
能够处理用户交互、事件监听和响应,例如点击事件、键盘事件和鼠标事件等。 - 支持异步操作:
JavaScript
中有许多常见的异步操作,如网络请求、文件读写和定时器等。事件循环机制使得这些异步操作可以以非阻塞的方式执行,提高代码的效率和可维护性。
What-事件循环究竟是什么
在 JavaScript 中,异步任务可以分为宏任务
和微任务
宏任务
一般包括了以下几种:
setTimeout
和setInterval
I/O
操作,如Ajax
、文件读取
等UI渲染
等
微任务
一般包括以下几种:
Promise.then()
和catch()
方法process.nextTick()
MutationObserver()
方法
JavaScript
中的事件循环机制由下面四个部分组成:
调用堆栈(
Call Stack
)
调用堆栈记录了JavaScript
代码的执行顺序。当代码开始执行时,会被顺序推入调用堆栈(Call Stack
),当函数执行完毕后,会从堆栈中弹出。由于JavaScript
是单线程的,所以在调用堆栈中只能有一个任务在执行。在执行宏任务的过程中,如果遇到了微任务会将其加入微任务队列;宏任务队列(
Task Queue
)
宏任务队列可以理解为存放宏任务的一个队列。当遇到宏任务时,它会被顺序加入到宏任务队列中。宏任务一般是异步任务,包括setTimeout
、setInterval
、I/O 操作
等。只有当前的宏任务执行完毕之后,才会执行下一个宏任务。微任务队列(
Microtask Queue
)
微任务队列也可以理解为存放微任务的一个队列。当遇到微任务时,它会被顺序加入到微任务队列中。在每个宏任务执行结束后,会检查微任务队列是否为空。如果不为空,就会执行微任务队列中的所有任务,直到微任务队列为空。渲染队列(
Render Queue
)
渲染队列主要是用于浏览器中的渲染,保存了在执行宏任务期间发生的所有页面渲染操作,例如修改了DOM
树中的节点内容。当宏任务执行完毕后,JavaScript
引擎会检查是否需要更新页面,如果需要,则进行渲染,否则跳过这个步骤。
How-事件循环机制是如何执行的
事件循环机制的执行过程可以分为以下几个步骤:
执行同步代码:
JavaScript
首先会执行当前的同步代码,即按照顺序执行代码块中的语句,直到遇到异步任务或事件。将异步任务放入任务队列:当遇到异步任务时,
JavaScript
会将其放入任务队列中,而不是立即执行。异步任务可以是定时器(setTimeout
、setInterval
)、网络请求(Ajax
、Fetch
)、Promise
等。这些异步任务会在特定的条件满足后被触发执行。监听事件队列:事件循环线程会持续监听事件队列,以检查是否有待处理的事件或异步任务。事件队列中存储了待处理的事件和异步任务。
执行事件处理或异步任务:当事件循环线程发现事件队列中有待处理的事件时,它会取出事件,并执行相应的事件处理函数。对于异步任务,当主线程空闲时,事件循环线程会从任务队列中取出任务,并执行相应的回调函数。
重复执行:一旦执行完一个事件处理或异步任务,事件循环线程会再次检查事件队列,看是否还有待处理的事件。如果有,它会继续执行下一个事件处理或异步任务。这个过程会一直重复,直到事件队列和任务队列都为空。
需要注意的是,事件循环机制是单线程的,意味着同一时间只能执行一个任务。当事件循环线程执行事件处理或异步任务时,其他任务需要等待。这也是为什么长时间运行的任务可能会阻塞主线程,导致页面或应用程序的响应性能下降。
Got-能从中收益什么
通过事件循环机制,JavaScript能够以非阻塞的方式处理异步任务和事件,提高代码的执行效率和用户体验。了解事件循环机制的执行过程对于编写高效的异步代码非常重要,因为它可以帮助你理解代码执行的顺序和如何处理异步操作。