千家信息网

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安全错误 数据库的锁怎样保障安全 什么是影响软件开发效率 画数据库实体图的工具 沈阳尖峰软件开发电话 智慧工地用什么服务器 厦门东信网络技术有限公司 小学网络安全自查报告范文 十大网络安全事件分析 国家图书馆出版的数据库 验证失败链接服务器出问题 qq浏览器网络安全怎么关 虹口区专业软件开发信息推荐 聪者听于无声网络安全 安徽税票安全接入服务器地址 江苏人工智能软件开发 确保机关网络安全得到落实 网柜和服务器柜的区别 网络安全评测的上位法 工业园区智能服务器市面价 宽带连接怎么输入服务器名 不同数据库同样的索引不走 服务器系统无法进入登录界面 数据库表格怎么查看 下学期网络技术教学计划 查找出含有字段的数据库 电脑服务器没有显示怎么关机 数据库中的身份验证模式 我的世界e联盟服务器 对于敏捷软件开发的描述 干软件开发因为怀孕没办法辞职 服务器2012开机密码忘了
0