*微任务: 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事件环的更多相关文章

  1. 麻烦把JS的事件环给我安排一下

    上次大家跟我吃饱喝足又撸了一遍PromiseA+,想必大家肯定满脑子想的都是西瓜可乐...... 什么西瓜可乐!明明是Promise! 呃,清醒一下,今天大家搬个小板凳,听我说说JS中比较有意思的事件 ...

  2. 我已经迷失在事件环(event-loop)中了【Nodejs篇】

    我第一次看到他事件环(event-loop)的时候,我是一脸懵,这是什么鬼,是什么循环吗,为什么event还要loop,不是都是一次性的吗? 浏览器中和nodejs环境中的事件环是有一些区别的,这里我 ...

  3. nodejs事件模块

    nodejs 事件模块 events 只有一个对象 EventEmitter . var EventEmitter = require('events').EventEmitter;var life ...

  4. EventEmitter:nodeJs事件触发机制

    Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列 Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.r ...

  5. nodejs事件的监听与事件的触发

    nodejs事件(Events) 一.事件机制的实现 Node.js中大部分的模块,都继承自Event模块(http://nodejs.org/docs/latest/api/events.html  ...

  6. 12.nodejs事件轮询机制

    一:nodejs事件轮询机制  就是  函数的执行顺序 <script type="text/javascript"> setImmediate(function(){ ...

  7. nodejs 事件机制

    node 事件机制   一 三种定时器 NodeJS中有三种类型的定时器:超时时间.时间间隔.即时定时器 1.超时时间:setTimeout(callback,delayMilliSeconds,[a ...

  8. javascript事件环微任务和宏任务队列原理

    哈喽!大家好!我是木瓜太香,我又来嘞,今天来说说前端面试中经常别问到的 JS 事件环问题. JS 事件环 JS 程序的运行是离不开事件环机制的,这个机制保证在发生某些事情的时候我们有机会执行一个我们事 ...

  9. Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

    声明:本文为原创博文,转载请注明出处. Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线程 ...

随机推荐

  1. C++知识点总结篇

    const在不同位置时的不同意义 指针类型前:声明一个指向常量的指针,程序中不能通过指针来改变它所指向的值,但指针本身的值可以改变,即指针可以指向其他数据: "*"号和指针名之间, ...

  2. 【HC89S003F4开发板】 2调度器

    HC89S003F4开发板调度器调试 一.前言 逛论坛看到有人给HC89做了调度器,调度部分直接操作堆栈的. 下载链接 下载下来调试看看. 二.用户代码 @实现效果 编译后led灯闪烁 #includ ...

  3. C++枚举类型教案

    一.枚举类型的应用场景 只需要将需要的变量值一一列举出来,便构成一个枚举类型. 二.枚举类型的定义 ·定义方式: enum 枚举类型名字{枚举常量表}: ·关键字enum:说明接下来定义的是一个枚举类 ...

  4. TZOJ5201: 数字游戏

    #include<stdio.h> int main() { ,j=; scanf("%I64d %I64d %I64d",&n,&k,&t); ...

  5. dotnet Core学习之旅(二):安装IDE

    [重要:文中所有外链不能确保永久有效] >开发工具 高效的开发必然需要一个优秀的集成开发环境(IDE) 对于.NET Core 2.x可以使用包括但不限于以下IDE来进行开发. Visual S ...

  6. 使用Spring Cloud OAuth2和JWT保护微服务

    采用Spring Security AOuth2 和 JWT 的方式,避免每次请求都需要远程调度 Uaa 服务.采用Spring Security OAuth2 和 JWT 的方式,Uaa 服务只验证 ...

  7. 怎样修改vim的缩进

    默认vim的tab缩进是八个空格, 太长了, 需要改短一点. 第一步: 找到vimrc文件所在位置 # find / -name vimrc 第二步: 找到以后用vim打开vimrc文件并增加下面两行 ...

  8. #448 div2 a Pizza Separation

    A. Pizza Separation time limit per test1 second memory limit per test256 megabytes inputstandard inp ...

  9. PX4/Pixhawk uORB

    PX4/Pixhawk的软件体系结构主要被分为四个层次 应用程序的API:这个接口提供给应用程序开发人员,此API旨在尽可能的精简.扁平及隐藏其复杂性 应用程序框架:这是为操作基础飞行控制的默认程序集 ...

  10. 查询自动生成Guid列

    --newid()可以在查询的时候自动生成Guid列 ' ordey by Random --创建对应的列 用 uniqueidentifier 类型 IF NOT EXISTS ( SELECT * ...