node中定时器, process.nextTick(), setImediate()的区别与联系
1.定时器
setTimeout()和setInterval()与浏览器中的API是一致的,定时器的问题在于,他并非精确的(在容忍范围内)。尽管事件循环十分快,但是如果某一次循环占用的时间较多,那么下次循环时,他也许已经超时很久了。比如通过setTimeout()设定一个任务在10毫秒后执行,但是在9毫秒后,有一个任务占用了5毫秒的cpu时间片,再次轮到定时器执行时,时间就已经过期4毫秒。
2.process.nextTick()
在未了解process.nextTick()之前,很多人也许为了立即异步执行一个任务,会这样调用setTimeout()来达到所需的效果:
setTimeout(function () {
//code
}, 0);
由于事件循环自身的特点,定时器的精确度不够。而事实上,采用定时器需要动用红黑树,创建定时器对象和迭代等操作,而setTimeout(fn, 0)的方式较为浪费性能。实际上process.nextTick()方法的操作相对较为轻量。
每次调用process.nextTick()方法,只会将回调函数放入队列中,在下轮tick时取出执行,定时器中采用红黑树的操作时间复杂度为O(lg(n)),nextTick()的时间复杂度为O(1),很明显,nextTick()更加高效。
3.setImmediate()
setImmediate()方法与process.nextTicl()方法十分类似,都是将回调函数延迟执行。在node V0.9.1之前,setImmediate()还没有实现,那时候实现类似的功能主要是通过process,nextTick()来完成。
4.nextTick()和setImmediate()区别与联系
process.nextTick()中的回调函数执行的优先级要高于setImmediate().这里的原因在于事件循环对观察者的检查是有先后顺序的,process.nextTick()属于idle观察者,setImmediate()属于check观察者。在每一个轮循环检查中,idle观察者先于I/O观察者,I/O观察者先于check观察者。
在具体实现上,process.nextTick()的回调函数保存在一个数组中,setImmediate()的结果则是保存在链表中。在行为上,process.nextTick()在每轮循环中会将该数组中的回调函数全部执行完,而setImmediate()在每轮循环中执行链表中的一个回调函数。下面是例子:
//加入两个nextTick()的回调函数
process.nextTick(function () {
console.log('nextTick延迟执行1');
});
process.nextTick(function () {
console.log('nextTick延迟执行2');
})
//加入两个setImmediate()的回调函数
setImmediate(function () {
console.log('setImmediate延迟执行1');
//进入下次循环
process.nextTick(function () {
console.log("强势插入!!");
});
});
setImmediate(function () {
console.log("setImmediate延迟执行2");
});
console.log("正常执行");
其执行结果如下:
正常执行
nextTick延迟执行1
nextTick延迟执行2
setImmediate延迟执行1
setImmediate延迟执行2
强势插入!!
node中定时器, process.nextTick(), setImediate()的区别与联系的更多相关文章
- Node.js的process.nextTick(callback)理解
Node.js是单线程的,基于事件循环,非阻塞 IO的.事件循环中使用一个事件队列,在每个时间点上,系统只会处理一个事件,即使电脑有多个CPU核心,也无法同时并行的处理多个事件.因此,node.js适 ...
- node中定时器的“先进”用法
var DSQ = setInterval(function(){ console.log('zzq'); },1000); setTimeout(function(){ clearInterval( ...
- node中 path.join 和 path.resovle 区别
console.log(__dirname) console.log('----') console.log(path.resolve(__dirname, '/a/b', '../')) conso ...
- 理解 Node.js 里的 process.nextTick()
有很多人对Node.js里process.nextTick()的用法感到不理解,下面我们就来看一下process.nextTick()到底是什么,该如何使用. Node.js是单线程的,除了系统IO之 ...
- node 中的global对象和process对象
官方文档:http://nodejs.cn/api/ 因为Node.js是运行在服务区端的JavaScript环境,服务器程序和浏览器程序相比,最大的特点是没有浏览器的安全限制了,而且,服务器程序必须 ...
- 【ask】Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
1.周五对nodejs tcp长连接服务器框架进行压测,一切开始比较常规(没什么特殊问题). 2.突然手一哆嗦,把压测用的客户端群一起关闭了. 3.这个时候nodejs的服务器爆出了"Cau ...
- Node.js中Process.nextTick()和setImmediate()的区别
一.Webstrom使用node.js IDE的问题 在区别这两个函数之前来说一下Webstrom使用node.js IDE的问题,在配置Node.js的IDE了,但setImmediate().re ...
- 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick
[摘要] 官网博文翻译,nodejs中的定时器 示例代码托管在:http://www.github.com/dashnowords/blogs 原文地址:https://nodejs.org/en/d ...
- 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick
目录 Event Loop 是什么? Event Loop 基本解释 事件循环阶段概览 事件循环细节 timers pending callbacks poll阶段 check close callb ...
随机推荐
- MongoDB学习第七篇 --- sql和mongodb对比
一.术语和概念的对比 SQL MongoDB database database row document or BSON document column field index index ...
- 原来你是这样的JAVA[02]-包、传参、构造器
一.包(package) 在java程序中,一个java源文件称为编译单元,以.java后缀命名.编译单元内可以有一个public类,类名必须与文件名相同.注意:每个编译单元只能有一个public类. ...
- python实现散列表的链表法
在散列中,链接法是一种最简单的碰撞解决技术,这种方法的原理就是把散列到同一槽中的所有元素 都放在一个链表中. 链接法有两个定理,定理一: 在简单一致散列的假设下,一次不成功查找的期望时间为O(1 + ...
- Python学习_05_条件、循环
条件 和其他语言类似,python中使用if...elif...else来形成分支,支持三目操作符 ?:,python中没有switch,但是缩进的特性让if...elif...else的结构同样便于 ...
- php 面向对象三大特点:封装、继承、多态
在讲解这三大特性前,我们先讲访问修饰符. php中有3中访问修饰符:public protected private: public:表示公有的:可在本类.子类.对象实例中访问. protected: ...
- Nginx 反向代理获取真实IP问题
一.前言 前文 Nginx 解决WebApi跨域二次请求以及Vue单页面问题 当中虽然解决了跨域问题带来的二次请求,但也产生了一个新的问题,就是如果需要获取用户IP的时候,获取的IP地址总是本机地址. ...
- 编码(ACSII unicod UTF-8)、QT输出中文乱码深入分析
总结: 1. qt输出中文乱码原因分析 qt的编程环境默认是utf-8编码格式(关于编码见下文知识要点一): cout << "中文" << endl; 程 ...
- 安装好的虚拟机,外部通过ssh工具连接,报connection failed
今天,新装了一台ubuntu虚拟机,安装成功以后,准备利用Xshell从外部访问linux,以减少切换,但是,在连接时,总是会报:connection failed. 于是,写下这篇随笔,以增加记忆且 ...
- blog建表操作
表思维导图: 数据库:表 from django.db import modelsfrom django.conf import settingsfrom django.contrib.auth. ...
- 使用CJSON库实现XML与JSON格式的相互转化
之前完成了一个两个平台对接的项目.由于这两个平台一个是使用json格式的数据,一个是使用xml格式的数据,要实现它们二者的对接就涉及到这两个数据格式的转化,在查阅相关资料的时候发现了这个CJSON库, ...