nodejs事件循环学习
2019-02-27 00:08
183 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Try_yang/article/details/87958279
nodejs的事件循环
- 前言
- node中的事件循环的几个阶段
- 1.Timers阶段
- 2.I/O callbacks
- 3.idle,prepare(不常用,未做研究)
- 4.Poll
- 5.Check
- 6.close callback
- 7.伪代码说明
前言
这是笔者的第一篇博客,写博客的目的也仅仅是对自己所学习的知识做一个总结,如有理解不正确的地方还请各路大神指出,希望在编程的道路上越走越远。
node中的事件循环的几个阶段
1.Timers阶段
此阶段主要用于处理定时器相关的回调函数
2.I/O callbacks
除了定时器,close事件以外的其他事件的回调函数
3.idle,prepare(不常用,未做研究)
4.Poll
轮询阶段,用来检查有没有新的事件出现,这些事件的回调方法可能出于其他几个事件循环阶段,这里可能发生阻塞
poll阶段的判断规则:
1.如果进入到poll阶段的时候有已经到期的定时器,那么直接执行定时器回调,比如说将定时器时间设置为0,将会直接执行
2.处理poll阶段对应的事件队列的事件
如果此时poll阶段的事件队列不是空,那么则按照先进先出的顺序执行事件
如果是空,判断是否进入check,是的话执行check阶段回调,没有进入check,那么poll阶段继续轮询,同时检查是否有定时器完成,有就直接进入到timers阶段,执行对应回调函数
5.Check
为setImmediate存在的一个循环阶段,当事件循环进入到poll后,就会检查代码是否调用了setImmediate,如果调用,则立刻跳出poll进入check阶段,执行回调,执行完毕后开始下一轮事件循环
6.close callback
如果产生一个close事件,该事件会被加入到对应的队列,close阶段执行完毕,本轮事件循环结束,进入下一轮循环
7.伪代码说明
// 事件循环本身相当于一个死循环,当代码开始执行的时候,事件循环就已经启动了 // 然后顺序调用不同阶段的方法 while(true){ // timer阶段 timer() // I/O callbacks阶段 IO() // idle阶段 IDLE() // poll阶段 poll() // check阶段 check() // close阶段 close() } // 在一次循环中,当事件循环进入到某一阶段,加入进入到check阶段,突然timer阶段的事件就绪,也会等到当前这次循环结束,再去执行对应的timer阶段的回调函数 // 下面看这里例子 const fs = require('fs') // timers阶段 const startTime = Date.now(); setTimeout(() => { const endTime = Date.now() console.log(`timers: ${endTime - startTime}`) }, 1000) // poll阶段(等待新的事件出现) const readFileStart = Date.now(); fs.readFile('./Demo.txt', (err, data) => { if (err) throw err let endTime = Date.now() // 获取文件读取的时间 console.log(`read time: ${endTime - readFileStart}`) // 通过while循环将fs回调强制阻塞5000s while(endTime - readFileStart < 5000){ endTime = Date.now() } }) // check阶段 setImmediate(() => { console.log('check阶段') }) /*控制台打印 check阶段 read time: 9 timers: 5008 通过上述结果进行分析, 1.代码执行到定时器setTimeOut,目前timers阶段对应的事件列表为空,在1000s后才会放入事件 2.事件循环进入到poll阶段,开始不断的轮询监听事件 3.fs模块异步执行,根据文件大小,可能执行时间长短不同,这里我使用的小文件,事件大概在9s左右 4.setImmediate执行,poll阶段暂时未监测到事件,发现有setImmediate函数,跳转到check阶段执行check阶段事件(打印check阶段),第一次时间循环结束,开始下一轮事件循环 5.因为时间仍未到定时器截止时间,所以事件循环有一次进入到poll阶段,进行轮询 6.读取文件完毕,fs产生了一个事件进入到poll阶段的事件队列,此时事件队列准备执行callback,所以会打印(read time: 9),人工阻塞了5s,虽然此时timer定时器事件已经被添加,但是因为这一阶段的事件循环为完成,所以不会被执行,(如果这里是死循环,那么定时器代码永远无法执行) 7.fs回调阻塞5s后,当前事件循环结束,进入到下一轮事件循环,发现timer事件队列有事件,所以开始执行 打印timers: 5008 ps: 1.将定时器延迟时间改为5ms的时候,小于文件读取时间,那么就会先监听到timers阶段有事件进入,从而进入到timers阶段执行,执行完毕继续进行事件循环 check阶段 timers: 6 read time: 5008 2.将定时器事件设置为0ms,会在进入到poll阶段的时候发现timers阶段已经有callback,那么会直接执行,然后执行完毕在下一阶段循环,执行check阶段,poll队列的回调函数 timers: 2 check阶段 read time: 7 */
node是单线程运行,所以每个时间只能处理一个事件,所以在事件循环中,本质上还是不同阶段的回调方法的同步调用,当一次循环结束后,再开始下一轮循环,已上是笔者对事件循环的理解,如果有理解不到位的地方,请各路大神指正
相关文章推荐
- nodejs事件循环学习笔记
- libevent源码学习-----event_base事件循环
- Node.js学习1:事件循环探究
- Nodejs学习事件模块
- nodejs异步I/O和事件循环
- sofsip学习系列--GLib学习笔记二,事件循环2
- libevent源码学习(二)事件循环event_base
- Nodejs学习item 2 -- events事件处理EventEmitter
- libev 学习笔记之主体事件循环
- muduo网络库学习(八)事件驱动循环线程池EventLoopThreadPool
- NodeJS 事件循环
- Node.js 学习(五)Node.js 事件循环
- muduo网络库学习(四)事件驱动循环EventLoop
- node js 学习(2)回调函数 事件循环 buffer stream 模块系统
- JavaScript学习--事件循环
- nodejs入门(04)-事件循环
- nodejs基础 -- 事件循环
- nodejs-事件循环
- JS基础学习第四天:条件控制语句、循环语句、函数模块、事件等通用代码块
- 【JavaScript 学习--12】JS深入理解调用栈,事件循环机制,回调队列