nodejs事件循环

简介

单线程

提到node,我们就可以立刻想到单线程、异步IO、事件驱动等字眼。首先要明确的是node真的是单线程的吗,如果是单线程的,那么异步IO,以及定时事件(setTimeout、setInterval等)又是在哪里被执行的。
其实,按照严格来说,node并不是单线程的。node中存在着多种线程,包括:

js引擎执行的线程

定时器线程(setTimeout, setInterval) : 倒计时结束后(异步)会把回调 放在事件队列里面

异步http线程(ajax)

node中的单线程是指js引擎只在唯一的主线程上运行

事件循环概述

主线程将所有任务都放在循环队列中,
然后由底层的libuv库从循环事件队列中取出任务分配给不同的线程去处理,
主线程同时也会进行回调处理,整个过程形成事件循环

nodejs实现异步机制的核心便是libuv,libuv承担着nodejs与文件、网络等异步任务的沟通桥梁

通过事件驱动模型实现了高并发和异步 I/O ,适合处理I/O密集型任务

六个阶段

node的事件循环共有六个阶段,在一次事件循环中这六个阶段按顺序会一直循环执行,直至事件处理完成。
在这里插入图片描述
每一个阶段有一个队列,event loop执行到该阶段时,会该阶段的队列里的所有callback,当队列callback为空时,或callback执行到上限的时,就跳至下一阶段进行执行。

各阶段描述

timers 阶段: 这个阶段执行timer(setTimeout、setInterval)的回调,该阶段新创建的setTimeout、setInterval 会继续放在下一个轮回循环阶段执行

pendding callbacks 阶段: 执行一些系统操作的回调(比如网络通信的错误回调);

idle, prepare 阶段: 仅node内部使用;

poll 阶段: 获取新的I/O事件, 适当的条件下node将阻塞在这里(比如:文件读取操作,http请求 回调 )
底层代码在poll阶段执行的时候,会传入一个timeout超时时间,timeout超时时间到了,则退出poll阶段,执行下一个阶段。

check 阶段: 执行setImmediate() 设定的callbacks;

close callbacks 阶段: 比如socket.on(‘close’, callback)的callback会在这个阶段执行。

事件循环执行过程

  • 执行前,会先执行同步任务、在执行process.nextTick 、微任务 ,在进入timers阶段

  • 在事件循环的每一个子阶段退出之前都会执行:process.nextTick(先执行于microtaks) microtaks.如果有的话

  • node 的初始化
    初始化 node 环境。
    执行输入代码
    执行 process.nextTick 回调。
    执行 microtasks。

  • 进入 event-loop

  • 进入 timers 阶段

  • 进入IO callbacks阶段。

  • 进入 idle,prepare 阶段:

  • 进入 poll 阶段
    在这里插入图片描述

  • 进入 check 阶段。

  • 进入 closing 阶段。

  • 检查是否有活跃的 handles(定时器、IO等事件句柄)。
    如果有,继续下一轮循环。
    如果没有,结束事件循环,退出程序。

例子

const fs = require('fs');
setTimeout(() => {
  // 新的事件循环的起点
  console.log('1');
});//没填默认为1,主线程执行时间大于1ms,所以在timer阶段先执行。如果设置为2ms的话,则会先执行setImmediate

// 异步io,读取需要时间,当setTimeout时间较短的时候,setTimeout会比它先
fs.readFile('./text.txt', { encoding: 'utf-8' }, (err, data) => {
  if (err) throw err;
  console.log('3');
});
setImmediate(() => {
  console.log('2');
});
// 1 2 3
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值