Nodejs之路:非I/O的异步API
本篇主要介绍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的更多相关文章
- Nodejs之路(一)—— Nodejs入门
不知不觉,现在已经习惯学一点东西,就写博客记录一下.这次学习Nodejs主要是在B站上看的视频教程,感觉讲的很是不错,所以我想把在看视频学习过程中的一些重要知识点记录下来方便以后自己快速查阅. --- ...
- 高性能IO设计模式之阻塞/非阻塞,同步/异步解析
提到高性能,我想大家都喜欢这个,今天我们就主要来弄明白在高性能的I/O设计中的几个关键概念,做任何事最重要的第一步就是要把概念弄的清晰无误不是么?在这里就是:阻塞,非阻塞,同步,异步. OK, 现在来 ...
- 【nodejs学习】3.进程管理及异步编程
进程管理 1.调用终端命令实现目录目录拷贝 var child_procress = require('child_procress'); var util = require('util'); fu ...
- [翻译]各个类型的IO - 阻塞, 非阻塞,多路复用和异步
同事推荐,感觉写的不错就试着翻译了下. 原文链接: https://www.rubberducking.com/2018/05/the-various-kinds-of-io-blocking-non ...
- 008. 阻塞&非阻塞、同步&异步
阻塞 非阻塞:关注的对象是调用者: 阻塞:调用者发起调用后,处于等待状态,直到该调用有返回: 非阻塞:调用者发起调用后,不需要等待返回,可以往下执行: 同步 异步: 关注的对象是被调用者: 同步:服 ...
- Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO
Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO Java 非阻塞 IO 和异步 IO 转自https://www.javadoop.com/post/nio-and-aio 本系 ...
- nodejs之路-[0]安装及简易配置
题外话: 之前写过ubuntu下编译nodejs- 传送门:Ubuntu15.04编译安装nodejsV0.12.3 只是如今基本在win下做开发了-. 就以这篇帖子为开头,作为我踏上nodejs之路 ...
- Redis源码解析:19Hiredis异步API代码解析
Hiredis中的异步API函数需要与事件库(libevent,libev, ev)一起工作.因为事件循环的机制,异步环境中的命令是自动管道化的.因为命令是异步发送的,因此发送命令时,必要情况下,需要 ...
- Code First系列之视图,存储过程和异步API
返回<8天掌握EF的Code First开发>总目录 本篇目录 视图View 存储过程 使用存储过程CRUD 异步API 本章小结 自我测试 本系列的源码本人已托管于coding上:点击查 ...
随机推荐
- rabbitMQ windows 安装 入门
转: https://www.cnblogs.com/junrong624/p/4121656.html 这里需要下载 rabbitmq, 我网盘里有今天没时间上传了,下次吧 1.下载,其实erlan ...
- 第一课了解SQL
1.1 数据库基础 其实一直在使用这数据库,当你在邮箱中查询名字时,当在网站上进行搜索,在自动取款机上使用ATM卡,这些操作都是在使用数据库 1.1.1 数据库 数据库:保存有组织的数据的容器(通 ...
- Python 快速排序 算法
基本的快排算法,二分法 #!/usr/bin/env python # encoding: utf-8 l1=[1,4,2,6,3] def path_sort(l,start_index,end_i ...
- Oracle 学习笔记(二)
一.索引 表的数据是无序的,所以叫堆表(heap table),意思为随机存储数据.因为数据是随机存储的,所以在查询的时候需要全表扫描.索引就是将无序的数据有序化,这样就可以在查询数据的时候 减少数据 ...
- leetcode981
考虑线性的搜索会超时,所以用二叉搜索来解决,代码如下: class TimeMap: def __init__(self): self.ST = dict() def set(self, key: ' ...
- .net core 微服务之日志落盘设计
原文:.net core 微服务之日志落盘设计 目录 1.设计目标 2.日志流程 3.串联请求事务 3.1 请求ID 3.2 处理服务器.服务 3.3 处理接口名 3.4 日志的发生时间 3.5 接口 ...
- SpringMVC Get请求传集合,前端"异步"下载excel 附SpringMVC 后台接受集合
最近项目上管理后台需要自己做一部分js部分,之前都是前端来弄...碰到了下载excel,刚开始使用ajax,搞了好久发现不合适..下载不了,网上说ajax返回类型不支持二进制流.. 因此采用 wind ...
- ==、equals和hashCode小结
1.== ==是关系操作符,对于基本类型(byte,short,char,int,long,float,double,boolean),比较的是值是否相等:对于对象,比较的是对象的引用(也即栈内存中的 ...
- python入门学习0
Python 是什么类型的语言 Python是脚本语言 Python下载地址:https://www.python.org/downloads/ Python版本:Python 3.4.2 - 64b ...
- Junit介绍以及使用
在介绍junit之前,把一些知识点提前了解一下 单元测试是一个对单一实体(类或方法)的测试. 测试用例(Test Case)是为某个特殊目标而编制的一组测试输入.执行条件以及预期结果,以便测试某个程序 ...