文章目录

  • 2 node中的事件循环模型
    • 2-1 一些属性
    • 2-2 循环模型
      • node事件循环总共有==六个阶段==
      • process.nextTick()函数
      • __实例__

2 node中的事件循环模型

2-1 一些属性

  • setInterval():----循环定时器

  • setTimeout();—延迟定时器

  • setImmendiate(); —立即执行函数

  • clearInterval();----清除循环定时器

  • clearTimeout();----清除演示定时器

  • clearImmendiate;----清除立即执行函数

/*立即执行函数*/setImmediate(()=>{console.log('我是异步执行的立即执行函数的回调函数');
})console.log('我是同步执行的任务');//我是同步执行的任务
// 我是异步执行的立即执行函数的回调函数// 执行结果与异步执行结果并无两样

setImmendiate即立即执行函数,
和setTimeout(()=>{})类似,虽然是立即到了执行时间,但因为是异步回调,最后的结果仍然是等主线程上的任务清空时,在执行回调

2-2 循环模型

  • 1 在node中有一种类似于js运行时的事件循环机制----事件轮询
  • 2 在主线程上的代码被清空时,node的事件轮询机制就会开启
  • 3 在轮询的过程中回调队列(消息队列)上若是有正在等待执行的回调函数,那么事件轮询将会对其进行相应的处理,若是没有回调函数正在等待执行,那么事件轮询将被挂起等待

node事件循环总共有六个阶段

  • 第一个阶段:timers

    定时器阶段:1 开始计时

    ​ 2 执行定时器的回调(setInterval,setTimeout)


  • 第二个阶段:pending callbacks

    系统阶段


  • 第三个阶段:idle prepare

    准备阶段


  • 第四个阶段:poll(核心)

    事件轮询阶段

1> 从队列里取出回调函数(除了定时器的回调),并同步执行,直到回调队列为空时,或者达到系统最大限度。

2> 如果回调队列为空时,继续判断是否有设置过setImmendiate

​ 1) 有设置过则进入下一个check阶段,这个阶段是专门用于执行setimmediate所在设置的回调。

​ 2) 没有则在此阶段停留,等待回调函数被插入回调队列。若这时有定时器的回调准备执行了,那么进入check阶段,目的:为了走第五个阶段,随后走第六个阶段,循环到第一阶段,执行定时器中的回调


  • 第五个阶段:check —专门用于执行setImmediate所设置的回调

  • 第六个阶段:close callbacks

关闭回调阶段


process.nextTick()函数

  • 能在任意阶段优先执行----除了主线程阶段

  • 用于设置立即执行函数

  • 和setImmendiate()类似

  • process.nextTick(()=>{});

    /*立即执行函数*/
    setImmediate(function () {console.log('我是异步执行的立即执行函数的回调函数');
    });
    console.log('我是同步执行的任务');
    //我是同步执行的任务
    // 我是异步执行的立即执行函数的回调函数
    process.nextTick(function () {console.log('这是process.nextTick()函数钩子执行的回调函数,并且执行了');
    });
    console.log('我是同步执行的任务2');// 我是同步执行的任务
    // 我是同步执行的任务2
    // 这是process.nextTick()函数钩子执行的回调函数,并且执行了
    // 我是异步执行的立即执行函数的回调函数
    

注意:

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

按照事件轮询模型,这里的输出应当是

setImmediate
setTimeout

但是在实际执行过程中我们发现它们的执行顺序前后都不一定

原因:在执行的过程中,如果事件轮询速度快过于定时器计时速度,那么先执行setImmediate,然后再执行setTimeout.

若事件轮询的速度慢于计时器计时,那么先执行setTimeout,在执行setImmediate

setTimeout(()=>{console.log('setTimeout')});setImmediate(()=>{console.log('setImmediate')});console.log('同步');

在代码里添加了同步任务,这里的执行结果又和之前的代码不一样了。执行顺序一直是 先setTimeout,再setImmediate

原因:因为主线程在执行的过程,setTimeout(()=>{})完成,且因为主线程执行过程中轮询机制并未开始轮询,所以在第一阶段setTimeout(()=>{})就已经执行了。


实例

console.log('1');setImmediate(() => {console.log('2');
});setTimeout(() => {console.log('3');
})setTimeout(() => {console.log('4')
}, 1000);console.log('5');// 1
// 5
// 3
// 2
// 4
// 解释
// 先执行同步任务,定时器开始计时完成后挂起回调,异步任务推到消息队列等待主线程执行完成
// 输出 1 5
// 主线程执行完成,无同步任务,于是开启事件轮询
// 在第一阶段中发现定时器的回调待执行,于是执行定时器的回调,
// 输出 3
// 进入第二,三阶段
// 进入第四阶段,发现回调队列为空(1s回调的定时器时长中,事件轮询已经执行很多次),判断是否有
// setImmediate,发现有,则将其推入第六个阶段执行,
// 进入第六个阶段,发现上个阶段的setImmediate有回调函数,执行回调函数
// 输出 2
// 进入第一个阶段,发现没有定时器执行完毕返回回调(定时器未完成)
// 进入第2,3,4阶段
// 发现回调队列没有任务,此时事件轮询将在此处停留等待
// 若此时1s定时器回调函数准备执行了,那么事件轮询将进入check阶段,然后到第一个阶段执行定时器回调
// 输出 4
// 进入 2,3,4阶段,发现回调队列无任务,无setImmendiate,无准备执行的定时器回调,轮询将被停留

Node中的事件轮询机制相关推荐

  1. 轮询机制php,JS事件轮询机制讲解

    JS是单线程语言,深入理解JS里的Event Loop,本文主要和大家分享JS事件轮询机制,希望能帮助到大家. JS的执行机制(一): 1.首先判断JS是同步还是异步,同步就进入主进程,异步就进入ev ...

  2. 事件轮询机制和promise(怪异机制?)

    事件轮询机制 任务队列分为 宏任务队列 微任务队列 ​ 当碰上异步代码时,会将异步代码传给web API 由web API 将异步代码放到任务队列中,script整体代码.setTimeout.set ...

  3. nodejs的事件轮询机制

    /* 面试题:nodejs的事件轮询机制*/setTimeout(function() {console.log('setTimeout()') }, 0)setImmediate(function( ...

  4. Node.js的事件轮询Event Loop原理解释

    事件轮询主要是针对事件队列进行轮询,事件生产者将事件排队放入队列中,队列另外一端有一个线程称为事件消费者会不断查询队列中是否有事件,如果有事件,就立即会执行,为了防止执行过程中有堵塞操作影响当前线程读 ...

  5. JS事件轮询机制(Event Loop)

    概念     事件轮询 (eventloop) 是"一个解决和处理外部事件时将它们转换为回调函数的调用的实体(entity)"     JavaScript 语言的一大特点就是单线 ...

  6. event loop 事件轮询机制

    1,event loop(事件轮询/事件循环) 首先我们要知道 由于js是单线程的脚本,异步事件要基于回调来实现的 而event loop 就是异步回调的实现原理 1,js的执行顺序 从前到后,一行一 ...

  7. MCDF中arbiter的轮询机制

    更新的MCDF的仲裁器采用的是Round Robin轮询的一个仲裁机制,简单来说就是最先被授权的通道在下一次仲裁中优先级会变为最低,这样可以保证每个通道都能够获得授权,而不是一个通道长时间连续的进行数 ...

  8. javaweb认识在web应用中重要的轮询机制(ajax)

    **轮询是用来解决服务器压力过大的问题的.**如果保持多个长连接,服务器压力会过大,因此.专门建立一个轮询请求的接口,里面只保留一个任务id,只需要发送任务id,就可以获取当前任务的情况.如果返回了结 ...

  9. 浏览器的进程,线程,事件轮询机制

    前言:其实网上关于js是单线程的文章很多,但是浏览器的线程,进程很多都没有提到,所以自己也进行了一个总结,将碎片化的知识进行梳理,形成一个知识体系,有问题的地方欢迎大家一起探讨. 首先,简单了解一下进 ...

最新文章

  1. 开源库nothings/stb的介绍及使用(图像方面)
  2. 17个Python的“正常“ 操作,你都OK吗?
  3. sql 关联使用id还是code_使用sh格式化nginx访问日志并存入mysql
  4. python与办公结合_python在办公时能给我们带来什么?
  5. matlab基本矩阵运算,科学网—matlab中矩阵基本运算 - 成爱芳的博文
  6. cookie和session原理
  7. 最近阅读20171106
  8. 阿里云云效如何保障双11大型项目管理
  9. 支付宝换上“读心术”AI客服,就为配合双11剁手的你
  10. Visio 画图去掉页边距(图形四周的空白区域)的解决办法
  11. 【GCN+KG】基于知识图谱和图卷积神经网络的应用和开发
  12. oracle用户删除了可以恢复吗,恢复用户误删除的没备份的Oracle数据文件
  13. mac使用nvm安装node进行多版本管理
  14. 苹果电脑如何快速用计算机,苹果电脑快捷键如何使用 Mac快捷键大全详细教程...
  15. Android接入TapTap踩坑
  16. 如何查看自己的外网 IP 地址
  17. 和君商学院A6选拔赛
  18. 2019年开发者必读!20位阿里技术大牛们帮你列了一份经典书单!
  19. 视频转换器怎么将ogv格式转换成mp4
  20. KONG 之 rate-limiting

热门文章

  1. React用户安全的第一道防线
  2. Linux下c语言创建文件目录
  3. Cocos2d-x :什么是锚点?(简单点说:锚点就是图片的原点)
  4. 命令快学神器——tldr工具的安装
  5. vb.net的循环语句
  6. diskgenius创建efi分区_Windows重建EFI引导启动分区(esp分区)
  7. idea插件安装后不显示问题
  8. java 0x80000000_如何在java中将0x80000000等同于-2147483648?
  9. 360屏蔽`停用开发者模式`消息.
  10. matlab中用于数据的标准化处理的zscore函数