事件循环

事件循环

异步操作会将相关回调添加到任务队列中,但是不是一声名就会进入任务队列,而是在不同的时机进入任务队列。而且,不同类型的异步操作添加到任务队列的时机也不同,比如 onclick, setTimeout,ajax 处理,他们添加到任务队列的时机都不同,这些异步操作是由浏览器内核的 webcore 来执行的,webcore 包含下图中的 3 种 webAPI,分别是 DOM Binding、network、timer 模块。
DOM Binding 模块处理一些 DOM 绑定事件,如 onclick 事件触发时,回调函数会立即被 webcore 添加到任务队列中。
network 模块处理 Ajax 请求,在网络请求返回时,才会将对应的回调函数添加到任务队列中。
timer 模块会对 setTimeout 等计时器进行延时处理,当时间到达的时候,才会将回调函数添加到任务队列中。
JS 只有一个线程,称之为主线程。而事件循环,是在主线程中的执行栈中的代码,执行完毕之后,才开始执行的。所以,主线程中要执行的代码时间过长,会阻塞事件循环的执行,也就会阻塞异步操作的执行。只有当主线程中执行栈为空的时候(即同步代码执行完后),才会进行事件循环来观察要执行的事件回调,当事件循环检测到任务队列中有事件就取出相关回调放入执行栈中由主线程执行。
事件循环,事件循环也有很多种,比如 window event loop、worker event loop,还有 worklet event loop
一个事件循环,有一个或者多个任务队列,一个任务队列是任务的集合,注意,微观任务队列(microTask queue)不是任务队列,任务队列实际上就是指宏观任务 macroTask 队列。
每一个任务都有一个任务源,任务源有以下几种:https://html.spec.whatwg.org/multipage/webappapis.html#generic-task-sources