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。
  • 相关阅读:
    shell脚本按当前日期输出日志
    bat弹出确认或取消窗口
    bat脚本输出日志
    北京浩赢科技有限公司与好宝多多
    bat延迟执行脚本,利用choice实现定时执行功能
    centos下安装tunctl
    OpenStack Train版 简单部署流程(4)- octavia
    LVM基础
    OpenStack Train版 简单部署流程(3)- ceilometer
    openstack stein
  • 原文地址:https://www.cnblogs.com/yayaxuping/p/10848966.html
Copyright © 2011-2022 走看看