Event Loop (事件循环)
Event Loop (事件循环)
1. 什么是Event Loop
在讲Event Loop 是什么之前,我们先了解一下为什么需要这个东西。
为什么需要Event Loop
首先,我们知道的是JS是单线程的,那既然只有一个线程来执行事件,就会产生一些问题,就比如一个场景,假如现在小张这边有一些任务,分别是看书、写作业、吃外卖、做广播体操;正常情况下,小张是写完作业之后,点一个外卖,等外卖送过来吃掉,再做广播体操。在这个过程中,小张其实会有一个“干等”的时间,也就是什么都不做,在那等外卖的时间。
单线程的JS和小张做事情是相似的,那小张比较懒,可以干等着,但是如果JS也干等着,那对于用户来说,这就发生了阻塞了呀,万万不可!!(准确一点来说,JS也没有干等着,它是自己在做那些耗时的事情,类比到这里就是自己去店里拿外卖)。
这个时候Event Loop就站出来了,它是一种可以让JS既是单线程,又不会阻塞的机制;人话就是,他通过一些手段,让JS执行事件的效率更高;既然你有一些耗费时间的事情,那就先把这些事情放在一边,先做立即可以完成的,等到那些耗时的事情有结果了,再去拿那个结果;到小张这里就是,点完外卖之后就开始做广播体操,做完广播体操,再吃送过来的外卖。
Event Loop
Event Loop是用来协调各种事件、用户交互、脚本执行、UI 渲染、网络请求等的一种机制。作用的方式就是,通过监控执行栈和任务队列,如果执行栈是空的,就从任务队列当中取出任务压入到执行栈当中执行,所以,他其实也就是一种异步的实现机制。
2. 前沿知识
同步事件与异步事件
同步事件指的是任务一件一件的完成,语句从上到下一条一条的执行,执行完成再执行下一条语句。就比如一条简简单单的console.log(xxx)
,就执行到它,打印就行,打印完了,就继续往下执行。对于小张来说,就是看书,写作业,做广播体操;
而异步事件是相对于同步来讲的,就是一些比较耗费时间的,它需要执行一系列的操作,但我们最后其实只需要知道它的结果就ok了,所以我们会把它执行的过程先挂起来,不让它影响我们后续要做的事情。就是把拿外卖的事情交给外卖员来做,小张继续做广播体操,最后再去吃外卖。
执行栈
执行栈会将当前的执行上下文(通俗一点可以理解成当前的函数调用)压入到执行栈当中,执行完成后就会把它弹出去。
任务队列
任务队列就是存放异步任务的队列,也没有什么特别的。但是在JavaScript
当中,有两种任务队列,一个是宏任务队列,一个是微任务队列。我们只需要知道哪些是宏任务、哪些是微任务,然后对应类型的任务放到相应的任务队列当中。
3. 事件循环过程
事件循环的作用方式是,通过监控执行栈和任务队列,如果执行栈是空的,就从任务队列当中取出任务压入到执行栈当中执行。
首先,执行全局Script代码,这些同步代码有一些是同步语句,有一些是异步语句;异步语句放入相应的任务队列,当执行栈在执行完同步任务后,查看执行栈是否为空,如果执行栈为空,就会去执行Task
(宏任务),每次宏任务执行完毕后,检查微任务(microTask
)队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务(microTask
)后,设置微任务(microTask
)队列为null
,然后再执行宏任务,如此循环。