Node定时器详解

时间:2021-10-09 00:11:29

原文章地址:http://mp.weixin.qq.com/s/FZefHsoVqtkcjUJK3KwRFw
    文章中主要讲了Node的四个定时器(setTimeout(),setInterval(),setImmediate(),process.nextTick())以及代码运行的规则。

  •  同步比异步代码更早执行
  • 异步代码中本轮循环比次轮循环更在执行,其中Node规定process.nextTick()和Promise的回调函数追加再本轮循环,而setTimeout()、setInterval()、setImmediate()是追加再次轮循环中的
  • process.nextTick()是异步事件中最快执行的
  • Promise的回调函数追加在process.nextTick()事件的微任务中,也被划为本轮循环
  • 事件循环的初始化过程 
    • 同步任务

    • 发出异步请求

    • 规划定时器生效的时间

    • 执行 process.nextTick()等等

  • 事件循环的六个阶段
    • timers    定时器阶段,若当前事件满足定时器条件,则执行定时器的回调函数,反之离开

    • I/O callbacks    执行除定时器和关闭请求的其他所有回调函数

    • idle, prepare    libuv内部调用,libuv是Node规定的库用来负责异步事件在主线程上的执行时间

    • poll    等待未返回的I/O事件,此阶段消耗事件较长

    • check    执行定时器的回调函数

    • close callbacks    执行用来关闭请求的回调函数,如 socket.on('close', ...)

  • 另外需要注意的是setTimeout的第二个参数默认为 0。但是实际上,Node 做不到0毫秒,最少也需要1毫秒,根据官方文档,第二个参数的取值范围在1毫秒到2147483647毫秒之间。即setTimeout(fn,0)等同于setTimeout(fn,1)
setTimeout(()=>console.log(1));    setImmediate(()=>console.log(2));


     理论上说上面两行代码的执行顺序应该是先打印1再打印2,但在实际操作中却是有可能先打印2再打印1的,取决于当时的系统状况,若进入事件循环到了1ms,就先打印1再打印2,若没有1ms,则回跳过setTimeout去执行setImmediate的回调。