Node.js的定时器

作者: 某尤 | 来源:发表于2016-04-08 15:13 被阅读895次

    Node 中的非 I/O 的异步 API,它们分别是 setTimeout()setInterval()setImmediate()process.nextTick()

    定时器

    setTimeout()setInterval()与浏览器中的API是一致的,分别用于单次和多次定时执行任务。

    缺点:定时器可能出现超时执行。例如通过setTimeout()设定一个任务在10毫秒后执行,但是在9好秒后,有一个任务占用了5毫秒的CPU时间片,再次轮到定时器执行时,时间就已经过期4毫秒。

    process.nextTick()

    在不了解 process.nextTick() 前,如果你为了立即异步执行一个任务,会这样调用 setTimeout() 来达到所需效果:

    setTimeout(function() {
      //TODO
    }, 0);
    

    由于事件循环自身的特点,定时器的精确度不够。而且采用定时器需要动用红黑树,创建定时器对象和迭代等操作,而 setTimeout(fn, 0) 的方式较为浪费性能。这时可以使用 process.nextTick() 方法,较为轻量级,具体代码如下:

    process.nextTick = function() {
      if (process._exiting) return;
    
      if (tickDepth >= process.maxTickDepth)
        maxTickWarn();
    
      var tock = { callback: callback };
    
      if (process.domain) tock.domain = process.domain;
      nextTickQueue.push(tock);
      if (nextTickQueue.length) {
        process._needTickCallback();
      }
    };
    

    每次调用 process.nextTick() 方法,只会将回调函数放入队列中,在下一轮Tick时取出执行。定时器中采用红黑树的操作时间复杂度为 O(lg(n)),nextTick() 的时间复杂度是 O(1)。

    setImmediate()

    setImmediate()process.nextTick() 十分类似,都是将回调函数延迟执行。

    process.nextTick(function () {
      console.log('nextTick延迟执行1');
      process.nextTick(function() {
        console.log('插入1');
      });
    });
    process.nextTick(function () {
      console.log('nextTick延迟执行2');
    });
    setImmediate(function () {
      console.log('setImmediate延迟执行1');
      process.nextTick(function () {
        console.log('插入2');
      });
    });
    setImmediate(function () {
      console.log('setImmediate延迟执行2');
    });
    console.log('正常执行');
    

    输出

    正常执行
    nextTick延迟执行1
    nextTick延迟执行2
    插入1
    setImmediate延迟执行1
    setImmediate延迟执行2
    插入2
    

    以上是读《深入浅出Node.js》一书的一些记录。

    相关文章

      网友评论

        本文标题:Node.js的定时器

        本文链接:https://www.haomeiwen.com/subject/uysvlttx.html