NodeJS事件环
- *微任务: promise.then < process.nextTick(先)
- 1. 主执行栈队列
- 2. timer队列: setTimeout/setInterval // 到时间后,将任务加入timer队列;没有到时间,且check队列为空,就切换到poll队列等待
- 3. poll队列: i/o接口,fs.readFile //如果check队列为空,会在此阶段等待定时器到达
- 4. check队列: setImmediate
1. 执行顺序说明
- node10及之前和node11之后的“微任务队列清空条件”不同:
- 1)node10及之前的版本,队列切换时才会清空微任务队列
- 2)node11及之后的版本,每执行一个宏任务就清空微任务队列(同浏览器)
1. node V10(每次切换都清空队列)
1. 清空主执行栈队列
2. 清空微任务队列。
3. 按照timer->poll->check队列执行,只要执行队列切换就清空微任务队列。则主执行栈切换到timer队列,也会先清空微任务队列。
4. 定时器时间到达,清空所有的timer队列。
5. 如果定时器时间未到达,到poll队列,查看check队列是否有任务,如果有,清空。否则,在poll队列等待。
6. 轮训timer队列是否有任务。
2. node V11+ (执行一次宏任务就清空微任务队列)
同浏览器事件环
1. 清空主执行栈队列
2.清空微任务队列
3.按照timer->poll-check队列。如果timer定时器时间不到,进入poll队列执行,然后检查check队列,有任务的话,先执行第一个,然后检查微任务队列,如果有任务则清空,再继续执行check队列的其他任务,每执行一次都要清空微任务队列;否则继续等待,直到定时器到达。
4.如果定时器时间到达,如果timer队列有多个任务,先执行第一个,然后取清空微任务队列,然后继续执行,每执行一个timer中的任务就清空一次微任务队列。
5.再进入poll队列,依timer->poll-check轮训
2. 应用
示例1:
- setTimeout(() => {
- console.log('timeout')
- })
- setImmediate(() => {
- console.log('immediate')
- })
- // node命令执行后,先后顺序不一定。根据setTimeout定时器的到达时间快慢。
- // 如果setTimout回调函数先进入队列,先执行;否则setImmediate先执行
示例2:
- const fs = require('fs');
- fs.readFile('1.txt', 'utf-8', function() {
- process.nextTick(() => {
- console.log('nexttick')
- })
- setTimeout(() => {
- console.log('settimeout')
- })
- setImmediate(() => {
- console.log('setImmediate')
- })
- })
- // 运行结果如下:
- nexttick
- setImmediate //按照事件环,一定先执行;因为fs是poll队列,poll队列->check队列
- settimeout
示例3:
- process.nextTick(() => {
- console.log('nexttick')
- })
- setTimeout(() => {
- console.log('settimeout1')
- })
- setTimeout(() => {
- console.log('settimeout2')
- })
- setImmediate(() => {
- console.log('setImmediate')
- process.nextTick(() => {
- console.log('immediate->nexttick')
- })
- })
- const fs = require('fs');
- fs.readFile('1.txt', 'utf-8', function() {
- process.nextTick(() => {
- console.log('fs->nexttick')
- })
- setTimeout(() => {
- console.log('fs->settimeout')
- })
- setImmediate(() => {
- console.log('fs->setImmediate')
- })
- })
- fs.readFile('1.txt', 'utf-8', function() {
- process.nextTick(() => {
- console.log('fs2->nexttick')
- })
- setTimeout(() => {
- console.log('fs2->settimeout')
- })
- setImmediate(() => {
- console.log('fs2->setImmediate')
- })
- })
- // node V10运行结果如下:
- nexttick
- settimeout1
- settimeout2
- fs->nexttick
- fs2->nexttick
- setimmediate
- fs->setImmediate
- fs2->setImmediate
- immediate->nexttick
- fs->settimeout
- fs2->settimeout
- // node V11运行结果如下
- nexttick
- settimeout1
- settimeout2
- fs->nexttick
- fs2->nexttick
- setimmediate
immediate->nexttick- fs->setImmediate
- fs2->setImmediate
- fs->settimeout
- fs2->settimeout
NodeJS事件环的更多相关文章
- 麻烦把JS的事件环给我安排一下
上次大家跟我吃饱喝足又撸了一遍PromiseA+,想必大家肯定满脑子想的都是西瓜可乐...... 什么西瓜可乐!明明是Promise! 呃,清醒一下,今天大家搬个小板凳,听我说说JS中比较有意思的事件 ...
- 我已经迷失在事件环(event-loop)中了【Nodejs篇】
我第一次看到他事件环(event-loop)的时候,我是一脸懵,这是什么鬼,是什么循环吗,为什么event还要loop,不是都是一次性的吗? 浏览器中和nodejs环境中的事件环是有一些区别的,这里我 ...
- nodejs事件模块
nodejs 事件模块 events 只有一个对象 EventEmitter . var EventEmitter = require('events').EventEmitter;var life ...
- EventEmitter:nodeJs事件触发机制
Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列 Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.r ...
- nodejs事件的监听与事件的触发
nodejs事件(Events) 一.事件机制的实现 Node.js中大部分的模块,都继承自Event模块(http://nodejs.org/docs/latest/api/events.html ...
- 12.nodejs事件轮询机制
一:nodejs事件轮询机制 就是 函数的执行顺序 <script type="text/javascript"> setImmediate(function(){ ...
- nodejs 事件机制
node 事件机制 一 三种定时器 NodeJS中有三种类型的定时器:超时时间.时间间隔.即时定时器 1.超时时间:setTimeout(callback,delayMilliSeconds,[a ...
- javascript事件环微任务和宏任务队列原理
哈喽!大家好!我是木瓜太香,我又来嘞,今天来说说前端面试中经常别问到的 JS 事件环问题. JS 事件环 JS 程序的运行是离不开事件环机制的,这个机制保证在发生某些事情的时候我们有机会执行一个我们事 ...
- Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现
声明:本文为原创博文,转载请注明出处. Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线程 ...
随机推荐
- hyperledger fabric超级账本java sdk样例e2e代码流程分析
一 checkConfig Before 1.1 private static final TestConfig testConfig = TestConfig.getConfig() ...
- Python调用API接口的几种方式
Python调用API接口的几种方式 相信做过自动化运维的同学都用过API接口来完成某些动作.API是一套成熟系统所必需的接口,可以被其他系统或脚本来调用,这也是自动化运维的必修课. 本文主要介绍py ...
- python学习-40 生产者和消费者模型
import time def buy(name): # 消费者 print('%s上街去买蛋' %name) while True: eggs=yield print('%s买了%s' %(name ...
- Django框架学习易错和易忘点
一.get在几处的用法 1.获取前端数据 request.POST.get('xxx') #当存在多个值时,默认取列表最后一个元素:所以当存在多个值时,使用getlist 2.获取数据库数据 mode ...
- PAT(B) 1089 狼人杀-简单版(Java)逻辑推理
题目链接:1089 狼人杀-简单版 (20 point(s)) 题目描述 以下文字摘自<灵机一动·好玩的数学>:"狼人杀"游戏分为狼人.好人两大阵营.在一局" ...
- SAS学习笔记54 RTF文件格式
Style RTF Control Word Example Code Italicize \i title '\i italicized title'; Underline \ul title '\ ...
- Vue、SPA实现登陆
axios/qs/vue-axios安装及使用步骤 首先我们要下载三个依赖包,方便后面的开发使用需要: npm install axios -S axios是vue2提倡使用的轻量版的ajax.它 ...
- AtomicIntegerFieldUpdater和AtomicInteger
为什么有了AtomicInteger还需要AtomicIntegerFieldUpdater? 当需要进行原子限定的属性所属的类会被创建大量的实例对象, 如果用AtomicInteger, 每个实例里 ...
- javascript序列化表单追加参数
js序列化表单后追加参数方式: 追加参数:token,status var data = $.param({"token":token, "status":st ...
- HTML 标签入门
HTML 简介 定义: 超文本标记语言(html)是标准通用标记语言下的一个应用,也是一种规范,一种标准 它通过标记符号来表示网页中的各个部分,网页文件本身是一种文本文件,通过在文本文件中添加标记符, ...