nodejs 事件循环机制

nodejs事件循环机制

nodejs是基于v8引擎的JavaScript运行时。(注意nodejs不是一门新的编程语言)

nodejs是基于libuv实现 异步非阻塞式i/o 操作的。而事件循环是nodejs处理非阻塞式I/O操作的机制。

以下是我理解的nodejs事件循环机制,如有问题,欢迎指正。

首先node10+的事件循环机制与浏览器端js的事件循环机制基本一致。

单线程or多线程

1、nodejs的主线程是单线程,那单线程如何完成异步操作呢?

基于底层c++ libuv库来实现。js通过V8引擎调用node API,node API底层由c++ libuv库实现,libuv库将接收到的不同异步操作分配给不同的线程,不同线程处理结束后已异步方式,将结果返回给v8引擎。

js任务分为同步任务和异步任务,异步任务分为微任务与宏任务。

正常js执行顺序为,执行栈中同步任务执行完毕,则执行全部微任务(清空微任务),此时主线程空闲,则执行***一次***宏任务(事件队列),继续执行执行栈,微任务队列,再执行一次宏任务。。依此反复。

在这里插入图片描述
1、主线程执行栈全部任务执行完毕。
2、检查微任务队列,process.nextTick优先级最高,总是最先执行。
3、检查宏任务队列,提取一次任务推入执行栈,进行执行。

2、宏任务包含 setTimeout i/o setImmediate等等这么多,如果后台都已操作完成,优先执行哪一个回调呢?

这才是事件循环的关键,特指上图右侧宏任务队列。事件循环就是为了解决异步操作。所以同步任务不属于事件循环,同时微任务也不属于事件循环的一部分。

事件循环如图分为6个阶段,每个阶段为一个FIFO回调队列(可理解为回调函数数组),按图顺序依次执行。事件循环每进入一个阶段,则将该阶段的回调队列用尽(全部执行完毕)或到最大限制回调数,则进入下一阶段。

举个栗子


//宏任务 check阶段 暂时命名任务1
setImmediate(()=>{
	console.log(1)
});
//宏任务 timer阶段   暂时命名任务2
setTimeout(()=>{
    console.log(2);
    //宏任务 timer阶段 暂时命名任务22
	setTimeout(()=>{
		console.log(22);
	},0);
},0);
//宏任务 timer阶段   暂时命名任务3
setTimeout(()=>{
	console.log(3);
},0);
//宏任务 timer阶段   暂时命名任务4
setTimeout(()=>{
	console.log(4);
},100);

//微任务              暂时命名任务5
process.nextTick(()=>{     
	console.log(5);
})
//同步任务                 暂时命名任务6
console.log(6);
console.log(7);
//执行结果为  6 7 5 2 3 1 22 4
我们看以上代码
步骤1 首先根据js执行顺序,从上到下依次执行,发现宏任务将任务放入下一个事件循环中,发现微任务,将其置入微任务队列中。将同步任务置入执行栈中。
步骤2 开始运行执行栈,其中有两行同步语句,输出 6 7,此时执行栈中运行完毕,主线程空闲;
步骤3 开始检查微任务队列,微任务队列中包含 process.nextTick,则输出5,微任务队列执行全部执行完毕,队列中再无其他微任务,则检查宏任务队列开始进行事件循环。
步骤4 事件循环进入第一阶段(timer阶段),检查是否有定时器超时的回调,此时发现队列中有两个回调(任务2和任务3回调)。
先执行任务2回调,输出 2。发现宏任务22,则将该任务放入下一次事件循环中(同步骤1。也同时符合执行一个宏任务则继续运行执行栈和微任务的解释)。
步骤5 任务2回调执行完毕,继续执行任务3回调。 (注意所有异步操作是后台操作完成可以触发回调函数时,才将回调函数放入对应阶段的队列中。所以此时timer队列中并无任务4回调)
步骤6 timer队列清空,事件循环进入下一阶段,依次到check阶段之前均为空队列,进入check阶段,执行任务1回调,输出1。继续进入close callback阶段。结束本次事件循环。
步骤7 进入下一个事件循环,timer阶段,队列中任务22回调,输出22。继续进入下面阶段,直到循环结束。
继续进入下一循环。。直到任务4超时回调触发 输出 4。

人生第一篇原创技术博文!

参考地址:
https://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttick/
https://www.cnblogs.com/linzhanfly/p/9082895.html

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值