当前位置: 首页 > 后端技术 > Node.js

什么是EventLoop机制

时间:2023-04-04 01:29:12 Node.js

首先我们来看看EventLoop是干什么用的。比如现在执行一个2s的setTimeout,浏览器主线程执行,然后在webAPI中调用setTimeout,然后浏览器的定时器线程开始计时,2s后事件触发线程开始处理setTimeout的回调函数,把这个回调函数丢进任务队列。这时事件循环开始执行任务队列。因此,事件循环可以理解为执行任务队列。在开始介绍事件循环之前,还有两个概念需要了解,分别是宏任务和微任务。宏任务和微任务是异步任务的两类:宏任务包括脚本、setTimeout/setInterval、setImmediate、I/O、UI渲染;微任务包括Promise、Object.observe、Mutation.Observer和postMessage。知道了它是做什么用的,知道了宏观任务和微观任务,我们就来看看它是什么。事件循环,直译为事件循环。事件是处理异步任务、宏任务和微任务,循环是循环处理。那么它是如何处理的呢?现在js主要有两种执行环境,一种是浏览器,一种是nodejs,两种环境都有相应的事件循环。我们分开说吧。浏览器的事件循环看图片。首先要执行的是脚本任务。脚本任务是全局任务,属于宏任务。宏任务执行完后,开始执行所有的微任务。执行可能只看这些或者不清楚,再举个例子。console.log(1);setTimeout(function(){console.log(2);},0);Promise.resolve().then(function(){console.log(3)});console.log(4);你认为这段代码将如何输出?输出结果:1432为什么?首先执行script全局任务,会输出1、4脚本执行完毕,开始判断microtask是否为空。现在明明有微任务Promise,然后开始执行Promise,执行完Promise输出3,清空微任务,微任务队列为空,然后重新渲染,再次判断任务队列中是否有任务此时任务队列中有setTimeout宏任务开始执行,所以最后输出2是一个完整的流程。一个事件循环有一个或多个任务队列,每个事件循环只有一个微任务队列。以上是浏览器的事件循环。nodejs的事件循环有6个阶段:timers:执行timers的回调pendingcallbacks:系统操作回调idle,pepare:内部使用poll:等待新的I/O事件check:执行setImmediatecallbackclosecallbacks:内部使用以上阶段,每个stage都有一个回调FIFO队列待执行,当事件循环运行到指定一个stage时,会执行该stage的fifo队列。当队列回调执行完毕或者回调执行次数超过该阶段上限时,事件循环将转入下一阶段。这6个阶段,我们现在只关注3个,分别是timer、poll和check。我们再看一张图。proccess.nextTick()是异步节点API,但不属于事件循环阶段。调用时,事件循环会停止,先执行该方法的回调。