参考:https://blog.csdn.net/weixin_42291355/article/details/108146890
js的事件运行机制,event loop 事件循环
首先要了解的是,js是单线程语言。
单线程的原因可简单理解为,由于js可以操作DOM,可以多线程操作的话,一个线程想修改DOM,一个线程想删除DOM,这样就非常容易出错,因次单线程是最安全的JS运行方式。
JS是单线程的,当我们开始执行一段代码时,从上至下依次执行。为了保证执行效率,JS事件任务有同步和异步两种方式。我们对同步和异步的处理是不一样的。
同步任务是当这个任务运行完成后,才可以继续下一步;异步任务是指运行当前的任务不影响接下来的任务。看起来似乎是多线程,但实际上还是单线程,异步的任务只是被放到队列中了,接下来会解释整个JS实践运行的机制。
如下图,当我们开始运行一段任务时(代码块),首先判断是否是同步任务,是的话就放在主线程中执行,如果是异步任务,则会放入到event table中,当指定的事情完成后,任务会推到event queue队列中。当主线程任务执行完毕后,会检查event queue是否有待执行的任务,有的话就执行,没有的话继续检查是否有任务执行。如此循环往复,就是JS的事件循环。
同步任务是直接放到执行栈中执行,异步事件放入到队列中,但异步事件哪个先哪个后,我们有更精细的划分,宏任务和微任务。
宏任务:setTimeout(),setInterval()、setImmediateI/O、UI交互事件、postMessage、MessageChannel
微任务:Promise.then、MutationObserver、process.nextTick(Node环境)
当遇到同步函数时,放入执行栈立即执行,遇到异步函数时,根据是宏任务或者微任务放到宏队列或者微队列中。执行栈执行完毕之后,首先检查队列中是否有微任务,有的话执行所有的微任务。然后再检查是否有宏任务,有的话执行宏任务,再次检查宏任务内有没有微任务,有的话执行左右的微任务。以此类推。