千家信息网

NodeJS事件循环实例分析

发表于:2024-10-22 作者:千家信息网编辑
千家信息网最后更新 2024年10月22日,这篇文章主要介绍"NodeJS事件循环实例分析",在日常操作中,相信很多人在NodeJS事件循环实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"NodeJS事件循
千家信息网最后更新 2024年10月22日NodeJS事件循环实例分析

这篇文章主要介绍"NodeJS事件循环实例分析",在日常操作中,相信很多人在NodeJS事件循环实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"NodeJS事件循环实例分析"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

浏览器中存在两个任务队列,一个是宏任务一个是微任务。但是在NodeJS中一共存在六个事件队列,timerspending callbacks,idle preparepoll,checkclose callbacks。每一个队列里面存放的都是回调函数callback

这六个队列是按顺序执行的。每个队列负责存储不同的任务。

  • timer里面存在的是setTimeout与setInterval的回调函数

  • pending callback是执行操作系统的回调,例如tcp,udp。

  • idleprepare只在系统内部进行使用。一般开发者用不到

  • poll执行与IO相关的回调操作

  • check中存放setImmediate中的回调。

  • close callbacks执行close事件的回调。

在Node中代码从上到下同步执行,在执行过程中会将不同的任务添加到相应的队列中,比如说setTimeout就会放在timers中, 如果遇到文件读写就放在poll里面,等到整个同步代码执行完毕之后就会去执行满足条件的微任务。可以假想有一个队列用于存放微任务,这个队列和前面的六种没有任何关系。

当同步代码执行完成之后会去执行满足条件的微任务,一旦所有的微任务执行完毕就会按照上面列出的顺序去执行队列当中满足条件的宏任务。

首先会执行timers当中满足条件的宏任务,当他将timers中满足的任务执行完成之后就会去执行队列的切换,在切换之前会先去清空微任务列表中的微任务。

所以微任务执行是有两个时机的,第一个时机是所有的同步代码执行完毕,第二个时机队列切换前。

注意在微任务中nextTick的执行优先级要高于Promise,这个只能死记了。

setTimeout(() => {    console.log('s1');})Promise.resolve().then(() => {    console.log('p1');})console.log('start');process.nextTick(() => {    console.log('tick');})setImmediate(() => {    console.log('st');})console.log('end');// start end tick p1 s1 st
setTimeout(() => {    console.log('s1');    Promise.resolve().then(() => {        console.log('p1');    })    process.nextTick(() => {        console.log('t1');    })})Promise.resolve().then(() => {    console.log('p2')})console.log('start');setTimeout(() => {    console.log('s2');    Promise.resolve().then(() => {        console.log('p3');    })    process.nextTick(() => {        console.log('t2');    })})console.log('end');// start end p2 s1 s2 t1 t2 p1 p3

Node与浏览器事件环执行是有一些不同的。

首先任务队列数不同,浏览器一般只有宏任务和微任务两个队列,而Node中除了微任务队列外还有6个事件队列。

其次微任务执行时机不同,不过他们也有相同的地方就是在同步任务执行完毕之后都会去看一下微任务是否存在可执行的。对浏览器来说每当一个宏任务执行完成之后就会清空一次微任务队列。在Node中只有在事件队列切换时才会去清空微任务队列。

最后在Node平台下微任务执行是有优先级的,nextTick优先于Promise.then, 而浏览器中则是先进先出。

setTimeout(() => {    console.log('timeout');})setImmediate(() => {    console.log('immdieate');})

在Node中时而会先输出timeout时而会先输出immdieate,这是因为setTimeout是需要接收一个时间参数的,如果没写就是一个0,我们都知道无论是在Node还是在浏览器,程序是不可能真的是0,他会受很多的因素影响。这取决于运行的环境。

如果setTimeout先执行就会放在timers队列中,这样timeout就会先输入,如果setTimeout因为某些原因后执行了,那么check队列中的immdieate就会先执行。这就是为什么时而输出timeout时而输出immdieate

const fs = require('fs');fs.readFile('./a.txt', () => {    setTimeout(() => {        console.log('timeout');    }, 0)    setImmediate(() => {        console.log('immdieate');    })})

这种情况就会一直先输出immdieate后输出timeout,这是因为,代码执行的时候会在timers里面加入timeout, 在poll中加入fs的回调,在check中加入immdieate。fs的回调执行结束之后实在poll队列,队列切换的时候首先会去看微任务,但是这里没有微任务就会继续向下,下面就是check队列而不是timers队列,所以poll清空之后会切换到check队列,执行immdieate回调。

到此,关于"NodeJS事件循环实例分析"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

任务 队列 事件 浏览器 切换 浏览 输出 不同 实例 实例分析 分析 循环 代码 就是 时机 条件 同步 学习 两个 优先级 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 数据库增加1怎么 网络安全大赛多少岁可以参加 如何正确利用网络技术 组态王历史报表与数据库的区别 限电影响网络安全吗 网络流媒体服务器多少钱一年 深圳市中升互联网科技 江苏科技网络安全 完美显示服务器已满 广州探途网络技术客服 关于软件危及网络安全的心得 数据库高级技术栈 计算机网络安全攻防教材 网络安全小品小学生 合肥参考网络技术咨询怎么样 软件开发工作室怎么办理营业执照 关系数据库表现为二维数组形式 反电诈网络安全知识你知道多少呢 浙江电力软件开发 sci数据库能修改作者吗 软件开发聊天功能 sql数据库连接失败请配置参数 数据库端口已被占用 学计算机网络技术基础是什么 在网络安全协会成立大会上的讲话 实时数据库开发需要学什么 一个社交软件开发难度 北京炼石网络技术有限公司地址 数据库如何输入颜色代码 中国移动基站有服务器吗
0