宏任务
script,setTimeoout,setInterval,setlmmediate(node 独有),I/o,render渲染
微任务
process.nextTick(),promise 
1,执行timers阶段,执行setTimeOut()和setInterval到期的calback
2,I/O callbacks: 上一轮循环中少数callback/Io会被延迟到这一阶段执行
3,idle,prepare:队列的移动紧内部实现
4,poll:执行I/O,适当的条件下会阻塞这个阶段
5,check:执行setlmmediate的calback
6,close calback:执行close 事件的calback
1,1 例子
浏览器和node执行顺序的区别
setTimeout(()=>{
    console.log('timer1')
    Promise.resolve().then(function() {
        console.log('promise1')
    })
}, 0)
setTimeout(()=>{
    console.log('timer2')
    Promise.resolve().then(function() {
        console.log('promise2')
    })
}, 0)
浏览器输出:
time1
promise1
time2
promise2
Node输出:
time1
time2
promise1
promise2
在这个例子中,Node的逻辑如下:
最初timer1和timer2就在timers阶段中。开始时首先进入timers阶段,执行timer1的回调函数,打印timer1,并将promise1.then回调放入microtask队列,同样的步骤执行timer2,打印timer2;
至此,timer阶段执行结束,event loop进入下一个阶段之前,执行microtask队列的所有任务,依次打印promise1、promise2。
例子2
setImmediate(() => {
  console.log('timer1')
  Promise.resolve().then(function () {
    console.log('promise1')
  })
})
setTimeout(() => {
  console.log('timer2')
  Promise.resolve().then(function () {
    console.log('promise2')
  })
}, 0)
Node输出:
timer1               timer2
promise1    或者     promise2
timer2               timer1
promise2             promise1
按理说setTimeout(fn,0)应该比setImmediate(fn)快,应该只有第二种结果,为什么会出现两种结果呢?
这是因为Node 做不到0毫秒,最少也需要1毫秒。实际执行的时候,进入事件循环以后,有可能到了1毫秒,也可能还没到1毫秒,取决于系统当时的状况。如果没到1毫秒,那么 timers 阶段就会跳过,进入 check 阶段,先执行setImmediate的回调函数。
另外,如果已经过了Timer阶段,那么setImmediate会比setTimeout更快,例如:
const fs = require('fs');
fs.readFile('test.js', () => {
  setTimeout(() => console.log(1));
  setImmediate(() => console.log(2));
});
上面代码会先进入 I/O callbacks 阶段,然后是 check 阶段,最后才是 timers 阶段。因此,setImmediate才会早于setTimeout执行。
3不同异步任务执行的快慢
setTimeout(() => console.log(1));
setImmediate(() => console.log(2));
Promise.resolve().then(() => console.log(3));
process.nextTick(() => console.log(4));
输出结果:4 3 1 2或者4 3 2 1
因为我们上文说过microTask会优于macroTask运行,所以先输出下面两个,而在Node中process.nextTick比Promise更加优先[3],所以4在3前。而根据我们之前所说的Node没有绝对意义上的0ms,所以1,2的顺序不固定。
4MicroTask队列与MacroTask队列
   setTimeout(function () {
       console.log(1);
   },0);
   console.log(2);
   process.nextTick(() => {
       console.log(3);
   });
   new Promise(function (resolve, rejected) {
       console.log(4);
       resolve()
   }).then(res=>{
       console.log(5);
   })
   setImmediate(function () {
       console.log(6)
   })
   console.log('end');
Node输出:
2 4 end 3 5 1 6
这个例子来源于《JavaScript中的执行机制》。Promise的代码是同步代码,then和catch才是异步的,所以4要同步输出,然后Promise的then位于microTask中,优于其他位于macroTask队列中的任务,所以5会优于1,6输出,而Timer优于Check阶段,所以1,6。

nodejs,事件轮询总结的更多相关文章

  1. 12.nodejs事件轮询机制

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

  2. nodejs事件轮询详述

    目录 概述 nodejs特点 事件轮询 关于异步方法 概述 关于nodejs的介绍网上资料非常多,最近由于在整理一些函数式编程的资料时,多次遇到nodejs有关的内容.所以就打算专门写一篇文章总结一下 ...

  3. 理解Node.js的事件轮询

    前言 总括 : 原文地址:理解Node.js的事件轮询 Node小应用:Node-sample 智者阅读群书,亦阅历人生 正文 Node.js的两个基本概念 Node.js的第一个基本概念就是I/O操 ...

  4. 面试题: nodejs 的事件轮询机制

    setTimeout(function(){ console.log('setTimeout()执行了') },0) setImmediate(function(){ console.log('set ...

  5. node.js事件轮询(1)

    事件轮询(引用) 事件轮询是node的核心内容.一个系统(或者说一个程序)中必须至少包含一个大的循环结构(我称之为"泵"),它是维持系统持续运行的前提.nodejs中一样包含这样的 ...

  6. 对Node.JS的事件轮询(Event Loop)的理解

    title: Node.JS的事件轮询(event loop)的理解 categories: 理解 tags: Node JS 机制 当我们知道I/O操作和创建新线程的开销是巨大的! 网站延迟的开销 ...

  7. Node.js的事件轮询Event Loop原理

    Node.js的事件轮询Event Loop原理解释 事件轮询主要是针对事件队列进行轮询,事件生产者将事件排队放入队列中,队列另外一端有一个线程称为事件消费者会不断查询队列中是否有事件,如果有事件,就 ...

  8. 理解JavaScript中的事件轮询

    原文:http://www.ruanyifeng.com/blog/2014/10/event-loop.html 为什么JavaScript是单线程 JavaScript语言的一大特点就是单线程,也 ...

  9. JS中的异步以及事件轮询机制

    一.JS为何是单线程的? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊.(在JAVA和c#中的异步 ...

随机推荐

  1. Qt 倒计时验证码按钮效果

    本来还想继承QTimer跟QPushButton去实现,后来发现可以使用两个QTimer来实现: 验证码倒计时间:(60s) 封装到widget类里: 需要这几个数据:Button,TimerA,Ti ...

  2. linux下命令行执行Python程序提示no moudle,路径问题

    在ide中执行python程序,已经设置好项目路径中. 但是在cmd中执行程序,所在路径是python的搜索路径,如果涉及到import引用就会报类似ImportError: No module na ...

  3. [POJ 1390] Blocking

    问题描述 Some of you may have played a game called 'Blocks'. There are n blocks in a row, each box has a ...

  4. laravel后台账户登录验证(5.5.48版本)

    首先我是菜鸟,对laravel框架也不是很熟悉,突然有一天心血来潮就想研究一下laravel的后台登录用户登录的流程, 虽然公司项目中有这样的一套流程,也看了好几遍,越看越简单,越看我就越会了,当自己 ...

  5. 传统IO拷贝与零拷贝技术比较

    1. 传统IO 由上面图知,传统io需要经过4次copy, 3次状态切换 第一次: 从硬盘 经过 DMA 拷贝 到 kernel buffer (内核buferr) 第二次: 从kernel buff ...

  6. 51nod1446 限制价值树

    有N个点(N<=40)标记为0,1,2,...N-1,每个点i有个价值val[i],如果val[i]=-1那么这个点被定义为bad,否则如果val[i] >=0那么这个点为定义为good. ...

  7. BUUCTF | [De1CTF 2019]SSRF Me

    解法一字符串拼接: 1.得到签名sign http://8fa4531c-1164-49b7-a700-70e77e6aacb7.node3.buuoj.cn/geneSign?param=flag. ...

  8. 神奇的hsl

    HSL色彩模式是工业界的一种颜色标准,是通过对色相(H).饱和度(S).明度(L)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的.今天我们看看这种色彩模式,能在CSS中产生什么神奇的变 ...

  9. ctcss

    CTCSS解码器基于非常窄的带通滤波器,其通过所需的CTCSS音调.滤波器的输出经过放大和整流,只要存在所需的音调,就会产生直流电压.直流电压用于打开,启用或取消静音接收器的扬声器音频级.当音调存在时 ...

  10. JavaScript中的十种操作符

    ①   一元操作符(参与的只有一个变量) 前置递增递减(语句解析到递增/递减时值就被改变了) 后置递增递减(整个语句执行后值再改变) 递增递减也可用于字符串,布尔值,对象等,结果都将是数值:   ;v ...