nodejs事件循环机制

nodejs是基于v8引擎的JavaScript运行时。(注意nodejs不是一门新的编程语言)

nodejs是基于libuv实现 异步非阻塞式i/o 操作的。而事件循环是nodejs处理非阻塞式I/O操作的机制。

以下是我理解的nodejs事件循环机制,如有问题,欢迎指正。

首先node10+的事件循环机制与浏览器端js的事件循环机制基本一致。

单线程or多线程

1、nodejs的主线程是单线程,那单线程如何完成异步操作呢?

基于底层c++ libuv库来实现。js通过V8引擎调用node API,node API底层由c++ libuv库实现,libuv库将接收到的不同异步操作分配给不同的线程,不同线程处理结束后已异步方式,将结果返回给v8引擎。

js任务分为同步任务和异步任务,异步任务分为微任务与宏任务。

正常js执行顺序为,执行栈中同步任务执行完毕,则执行全部微任务(清空微任务),此时主线程空闲,则执行***一次***宏任务(事件队列),继续执行执行栈,微任务队列,再执行一次宏任务。。依此反复。


1、主线程执行栈全部任务执行完毕。
2、检查微任务队列,process.nextTick优先级最高,总是最先执行。
3、检查宏任务队列,提取一次任务推入执行栈,进行执行。

2、宏任务包含 setTimeout i/o setImmediate等等这么多,如果后台都已操作完成,优先执行哪一个回调呢?

这才是事件循环的关键,特指上图右侧宏任务队列。事件循环就是为了解决异步操作。所以同步任务不属于事件循环,同时微任务也不属于事件循环的一部分。

事件循环如图分为6个阶段,每个阶段为一个FIFO回调队列(可理解为回调函数数组),按图顺序依次执行。事件循环每进入一个阶段,则将该阶段的回调队列用尽(全部执行完毕)或到最大限制回调数,则进入下一阶段。

举个栗子


//宏任务 check阶段 暂时命名任务1
setImmediate(()=>{console.log(1)
});
//宏任务 timer阶段   暂时命名任务2
setTimeout(()=>{console.log(2);//宏任务 timer阶段 暂时命名任务22setTimeout(()=>{console.log(22);},0);
},0);
//宏任务 timer阶段   暂时命名任务3
setTimeout(()=>{console.log(3);
},0);
//宏任务 timer阶段   暂时命名任务4
setTimeout(()=>{console.log(4);
},100);//微任务              暂时命名任务5
process.nextTick(()=>{     console.log(5);
})
//同步任务                 暂时命名任务6
console.log(6);
console.log(7);
//执行结果为  6 7 5 2 3 1 22 4
我们看以上代码
步骤1 首先根据js执行顺序,从上到下依次执行,发现宏任务将任务放入下一个事件循环中,发现微任务,将其置入微任务队列中。将同步任务置入执行栈中。
步骤2 开始运行执行栈,其中有两行同步语句,输出 6 7,此时执行栈中运行完毕,主线程空闲;
步骤3 开始检查微任务队列,微任务队列中包含 process.nextTick,则输出5,微任务队列执行全部执行完毕,队列中再无其他微任务,则检查宏任务队列开始进行事件循环。
步骤4 事件循环进入第一阶段(timer阶段),检查是否有定时器超时的回调,此时发现队列中有两个回调(任务2和任务3回调)。
先执行任务2回调,输出 2。发现宏任务22,则将该任务放入下一次事件循环中(同步骤1。也同时符合执行一个宏任务则继续运行执行栈和微任务的解释)。
步骤5 任务2回调执行完毕,继续执行任务3回调。(注意所有异步操作是后台操作完成可以触发回调函数时,才将回调函数放入对应阶段的队列中。所以此时timer队列中并无任务4回调)
步骤6 timer队列清空,事件循环进入下一阶段,依次到check阶段之前均为空队列,进入check阶段,执行任务1回调,输出1。继续进入close callback阶段。结束本次事件循环。
步骤7 进入下一个事件循环,timer阶段,队列中任务22回调,输出22。继续进入下面阶段,直到循环结束。
继续进入下一循环。。直到任务4超时回调触发 输出 4。

人生第一篇原创技术博文!

参考地址:
https://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttick/
https://www.cnblogs.com/linzhanfly/p/9082895.html

nodejs 事件循环机制相关推荐

  1. boost log 能不能循环覆盖_前端基础进阶(十四):深入核心,详解事件循环机制...

    Event Loop JavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了.为了解决自己的这个困扰,在学习的过程中,我一直在试图 ...

  2. js中如何得到循环中的点击的这个id_Js篇面试题9请说一下Js中的事件循环机制

    虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 如果不知道如 ...

  3. js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)...

    javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...

  4. QT消息/事件循环机制与多线程的关系

    关于Qt子线程和消息循环 一.QT消息/事件循环机制 Qt作为一个可视化GUI界面操作系统,是基于事件驱动的,我们程序执行的顺序不再是线性,而是由一个个应用程序内部或外部的事件进行驱动,无事件时便阻塞 ...

  5. es5如何实现promise_ES5实现Promise(1) - 事件循环机制

    因为公司业务面向国企以及传统企业,所以代码需要能够在ie9以上运行,所以在项目中无法用一些新技术.比如ES6的Promise,这个Promise真的是太好使了,就跟便秘时使了开塞露一般.由于Promi ...

  6. JS事件循环机制:同步与异步任务 之 宏任务 微任务

    JS事件循环机制:同步与异步任务 之 宏任务 微任务 阅读目录 javascript事件循环 setTimeout和setInterval中的执行时间 宏任务和微任务 javascript是单线程,一 ...

  7. 事件循环机制 + ES7:Async/Await(基于generator原理实现)附详细示例分析

    文章目录 一.事件循环 任务队列 宏任务和微任务 循环机制 简单示例 二.Async/Await 1. async 2. await 3. 原理 4. 示例(红字分析为关键) 一.事件循环 任务队列 ...

  8. 浏览器中的事件循环机制

    浏览器中的事件循环机制 网上一搜事件循环, 很多文章标题的前面会加上 JavaScript, 但是我觉得事件循环机制跟 JavaScript 没什么关系, JavaScript 只是一门解释型语言, ...

  9. 浏览器事件循环机制与Vue nextTick的实现

    浏览器事件循环机制 先上一段简单的代码 console.log('aa'); setTimeout(() => { console.log('bb')}, 0); Promise.resolve ...

最新文章

  1. .NET Core微服务系列基础文章索引(目录导航Final版)
  2. HLS中数据的合并与拆分
  3. 不为人知的稠密特征加入CTR预估模型的方法
  4. Linux服务器安装JavaWeb环境(四) Sentinel,Xxl-Job,Seata
  5. Android SDK Manager配置
  6. 在 Linux 命令行发送邮件的 5 种方法
  7. python牛顿法与拟牛顿法_python实现牛顿法求解求解最小值(包括拟牛顿法)【最优化课程笔记】...
  8. java前端 js弹出框_前端js弹出框组件使用方法
  9. ubantu卸载MySQL数据库
  10. 如何将苹果手机投屏到电脑上
  11. mitmproxy的介绍以及配置过程中的问题
  12. (转载)费玉清生活清贫 是低调大富翁
  13. 如何查计算机硬盘型号,win10电脑的硬盘型号如何查看
  14. 秦岚微博之夜喜提热搜第一 优雅公主裙演绎真人版辛德瑞拉
  15. 并发编程的三大特性——原子性,可见性,有序性
  16. JavaScript学习笔记[红皮书]
  17. InfoPath 系列:了解INFOPATH XSN文件的格式(1)
  18. 【渝粤教育】广东开放大学 电子支付与安全 形成性考核 (59)
  19. 数据分析(七)之pandas学习【dataFrame的使用】
  20. js reduce函数

热门文章

  1. 又双叒叕拿奖!腾讯安全天御荣获“联邦学习应用奖”
  2. 【LINUX】Linux防火墙端口号设置
  3. vue 路由传参的8种方式 转
  4. 一个三目表达式,引起的空指针
  5. Linux使用XVFB做Selenium测试
  6. Json 格式的接口测试该怎么做?
  7. linux--smartctl
  8. Python与数据库[2] - 关系对象映射/ORM[1] - sqlalchemy 的基本使用示例
  9. Color android
  10. navicat导入sql数据库文件的简单操作步骤