本篇主要介绍setTimeout,setInterval,setImmediate和process.nextTick。

1,定时器

Node中的定时器和浏览器中用法一致。区别在于:在Node中,执行到setTimeout或setInterval的时候,会生成一个定时器,调用setTimeout或setInterval创建的定时器会被插入到定时器观察者内部的一个红黑树中。每次事件循环,会从这个红黑树中迭代取出定时器对象,检查是否超过定时时间,如果超过了,就形成一个事件,它的回调函数立即执行。

换句话说,执行定时器,就会有一个定时器观察者,每次事件循环,观察者就会去看定时器到点儿没,到了就执行回调。虽然每次事件循环很快,但是也会存在某个任务占用CPU时间片较长,然后超过了定时器的时间,导致等观察者去检查的时候,已经过了时间了。

这个和浏览器机制类似,但是浏览器好像没有观察者这一概念(没有在event loop文档里看到)

2,process.nextTick()

这个方法的效果就跟它的命名一样,将回调函数推入到下一次Tick,相比于定时器,它的复杂度较低,更高效,因为它不需要迭代红黑树,而是直接将回调函数放入队列中。

至于它的执行速度,知乎上讨论的比较激烈,我站队这个说法:

3,setImmediate

也是将回调函数延迟执行,但是优先级方面,process.nextTick()中的回调函数执行的优先级要高于setImmediate()。这里的原因是在于事件循环对观察者的检查是有先后顺序的,process.nextTick()属于idle观察者,setImmediate()属于check观察者。在每一个轮循环检查中,idle观察者先于I/O观察者,I/O观察者先于check观察者。

在具体实现上,两者也有差异,process.nextTick()的回调函数是在一个数组中,而setImmediate()的结果则是保存在链表中。在行为上,process.nextTick()在每轮循环中会将数组的回调函数全部执行完,而setImmediate()在每轮循环中执行链表中的一个回调函数。

setImmediate(function(){
console.log('setImmediate 1');
process.nextTick(function(){
console.log('process 1')
})
}); setImmediate(function(){
console.log('setImmediate 2')
});

上面代码执行结果:

setImmediate 1
process 1
setImmediate 2

可以看出执行完setImmediate 1以后并没有执行setImmediate 2,而是执行了下一轮循环,然后先执行了process 1,然后再执行了setImmediate 2。这样设计的目的是为了保证每轮循环能够较快地执行结束,防止CPU占用过多而阻塞后续I/O调用的情况。看来process.nextTick还真的是微任务,而且不光是这样,在node环境下,process.nextTick的执行优先级高于promise的回调。

end

Nodejs之路:非I/O的异步API的更多相关文章

  1. Nodejs之路(一)—— Nodejs入门

    不知不觉,现在已经习惯学一点东西,就写博客记录一下.这次学习Nodejs主要是在B站上看的视频教程,感觉讲的很是不错,所以我想把在看视频学习过程中的一些重要知识点记录下来方便以后自己快速查阅. --- ...

  2. 高性能IO设计模式之阻塞/非阻塞,同步/异步解析

    提到高性能,我想大家都喜欢这个,今天我们就主要来弄明白在高性能的I/O设计中的几个关键概念,做任何事最重要的第一步就是要把概念弄的清晰无误不是么?在这里就是:阻塞,非阻塞,同步,异步. OK, 现在来 ...

  3. 【nodejs学习】3.进程管理及异步编程

    进程管理 1.调用终端命令实现目录目录拷贝 var child_procress = require('child_procress'); var util = require('util'); fu ...

  4. [翻译]各个类型的IO - 阻塞, 非阻塞,多路复用和异步

    同事推荐,感觉写的不错就试着翻译了下. 原文链接: https://www.rubberducking.com/2018/05/the-various-kinds-of-io-blocking-non ...

  5. 008. 阻塞&非阻塞、同步&异步

    阻塞 非阻塞:关注的对象是调用者: 阻塞:调用者发起调用后,处于等待状态,直到该调用有返回: 非阻塞:调用者发起调用后,不需要等待返回,可以往下执行: 同步 异步:  关注的对象是被调用者: 同步:服 ...

  6. Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO

    Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO Java 非阻塞 IO 和异步 IO 转自https://www.javadoop.com/post/nio-and-aio 本系 ...

  7. nodejs之路-[0]安装及简易配置

    题外话: 之前写过ubuntu下编译nodejs- 传送门:Ubuntu15.04编译安装nodejsV0.12.3 只是如今基本在win下做开发了-. 就以这篇帖子为开头,作为我踏上nodejs之路 ...

  8. Redis源码解析:19Hiredis异步API代码解析

    Hiredis中的异步API函数需要与事件库(libevent,libev, ev)一起工作.因为事件循环的机制,异步环境中的命令是自动管道化的.因为命令是异步发送的,因此发送命令时,必要情况下,需要 ...

  9. Code First系列之视图,存储过程和异步API

    返回<8天掌握EF的Code First开发>总目录 本篇目录 视图View 存储过程 使用存储过程CRUD 异步API 本章小结 自我测试 本系列的源码本人已托管于coding上:点击查 ...

随机推荐

  1. 20165312 2017-2018-2 《JAVA程序设计》第5周学习总结

    20165312 2017-2018-2 <JAVA程序设计>第5周学习总结 一.本周学习内容总结 总的来说,本周学习较吃力,在理解第十章的代码时速度较慢. 内部类 内部类是定义在一个类中 ...

  2. DataBaseDaoAbstract

    import java.lang.reflect.Method; import java.math.BigDecimal; import java.sql.PreparedStatement; imp ...

  3. 关于element-ui日期选择器disabledDate使用心得

    实现目的: 使用type="data"类型实现具备开始日期与结束日期组件(ps:element有自带的type="daterange"类型的组件可以实现此功能) ...

  4. android 开发 View _14 MotionEvent和事件处理详解,与实践自定义滑动条View

    转载https://blog.csdn.net/huaxun66/article/details/52352469 MotionEvent MotionEvent对象是与用户触摸相关的时间序列,该序列 ...

  5. 装饰器 -- 函数装饰器(tornado异常响应装饰器)

    # 值可变,每次使用需要重新赋值 ERR_RESP_TEMPLATE = {"state": "FAILED", "error": None ...

  6. 1. redis安装(windows)

    Redis在windows下安装过程 转载自(http://www.cnblogs.com/M-LittleBird/p/5902850.html)   一.下载windows版本的Redis 去官网 ...

  7. leetcode337

    /** * Definition for a binary tree node. * public class TreeNode { * public int val; * public TreeNo ...

  8. HTML5-canvas1.0

    HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成.<canvas> 标签只是图形容器,您必须使用脚本来绘制图形.你可以通过多种方 ...

  9. netbeans 正则替换

    单引号替换为双引号: tablename1('xhw_aa')  tablename2('xhw_bb') tablename3('xhw_cc') tablename4('xhw_dd')   (t ...

  10. JavaScript学习-4——DOM对象、事件

    本章目录 --------window对象 --------document对象 --------事件 一.window对象 函数调用: 自己封装的函数只写:函数名(): 数学函数Math 例:绝对值 ...