zoukankan      html  css  js  c++  java
  • nodejs,事件轮询总结

    宏任务
    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。
  • 相关阅读:
    Maximum Depth of Binary Tree
    Single Number
    Merge Two Sorted Lists
    Remove Nth Node From End of List
    Remove Element
    Remove Duplicates from Sorted List
    Add Two Numbers
    编译视频直播点播平台EasyDSS数据排序使用Go 语言 slice 类型排序的实现介绍
    RTMP协议视频直播点播平台EasyDSS在Linux系统中以服务启动报错can’t evaluate field RootPath in type*struct排查
    【解决方案】5G时代RTMP推流服务器/互联网直播点播平台EasyDSS实现360°全景摄像机VR直播
  • 原文地址:https://www.cnblogs.com/yayaxuping/p/10848966.html
Copyright © 2011-2022 走看看