细说setTimeout/setImmediate/process.nextTick的区别
node.js中的非IO的异步API提供了四种方法,分别为setTimeOut(),setInterval(),setImmediate()以及process.nextTick(),四种方法实现原理相似,但达到的效果略有区别:
一、事件循环Event Loop
首先,我们需要了解node.js的基于事件循环的事件模型,正是因为它才使得node.js中回调函数十分普遍,也正是基于此,node.js实现了单线程高效的异步IO(这里说的单线程主要说的是执行javascript代码部分的线程,而异步IO部分node.js其实还是利用线程池去执行的)。
简单的讲就是,在node.js启动时,创建了一个类似while(true)的循环体,每次执行一次循环体称为一次tick,每个tick的过程就是查看是否有事件等待处理,如果有,则取出事件极其相关的回调函数并执行,然后执行下一次tick。所以,有如下代码:
A();
B();
C();
- 1
- 2
- 3
它的执行逻辑是,先询问事件观察者当前是否有任务需要执行?观察者回答“有”,于是取出A执行,A是否有回调函数?如果有(如果没有则继续询问当前是否有任务需要执行),则取出回调函数并执行(注意:回调函数的执行基本都是异步的,可能不止一个回调),执行完回调后通过某种方式通知调用者,我执行完了,并把执行结果给你,你自己酌情处理吧,主函数不需要不断询问回调函数执行结果,回调函数会以通知的方式告知调用者我执行完了(don’t call me ,i will call you.),而这个过程主线程并不需要等待回调函数执行完成,它会继续向前执行,即再次询问观察者当前是否还有任务需要执行,重复上面的步骤。。。直到观察者回答没有了,线程结束。
整个事件循环的逻辑如下图:
二:setTimeOut(),setInterval(),setImmediate()以及process.nextTik()
这里面setTimeOut()与setInterval()除了执行频次外基本相同,都表示主线程执行完一定时间后立即执行,而setImmediate()与之十分相似,也表示主线程执行完成后立即执行。那么他们之间的区别是什么呢?
代码如下:
setTimeout(function(){
console.log("setTimeout");
},0);
setImmediate(function(){
console.log("setImmediate");
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
两者都代表主线程完成后立即执行,其执行结果是不确定的,可能是setTimeout回调函数执行结果在前,也可能是setImmediate回调函数执行结果在前,但setTimeout回调函数执行结果在前的概率更大些,这是因为他们采用的观察者不同,setTimeout采用的是类似IO观察者,setImmediate采用的是check观察者,而process.nextTick()采用的是idle观察者。
三种观察者的优先级顺序是:idle观察者>>io观察者>check观察者
process.nextTick()与setImmediate()和setTimeout()的区别如下:
1、原始代码:
A();
B();
C();
- 1
- 2
- 3
它的执行顺序即代码顺序:
2、process.nextTick()执行效果,代码如下:
A();
process.nextTick(B);
C();
- 1
- 2
- 3
它的执行顺序如下:
3、setImmediate()或者setTimeout()执行效果,代码如下:
A();
setImmediate(B);//或者setTimeout(B,0);
C();
- 1
- 2
- 3
它的执行顺序如下:
结论:
process.nextTick(),效率最高,消费资源小,但会阻塞CPU的后续调用;
setTimeout(),精确度不高,可能有延迟执行的情况发生,且因为动用了红黑树,所以消耗资源大;
setImmediate(),消耗的资源小,也不会造成阻塞,但效率也是最低的。
细说setTimeout/setImmediate/process.nextTick的区别的更多相关文章
- setTimeout和setImmediate以及process.nextTick的区别
在javascript中我们了解到了setTimeout和setInterVal函数事件队列(任务队列)的相关知识,除了setTimeout和setInterval这两个方法外,Node.js还提供了 ...
- 比较setImmediate(func),setTimeout(func),process.nextTick(func)
node中的事件优先级机制: console.log('第一笔!'); process.nextTick(function() { console.log('吃个饭吧!'); setImmediata ...
- setTimeout,setInterval,process.nextTick,setImmediate in Nodejs
Nodejs的特点是事件驱动,异步I/O产生的高并发,产生此特点的引擎是事件循环,事件被分门别类地归到对应的事件观察者上,比如idle观察者,定时器观察者,I/O观察者等等,事件循环每次循环称为Tic ...
- Node.js中Process.nextTick()和setImmediate()的区别
一.Webstrom使用node.js IDE的问题 在区别这两个函数之前来说一下Webstrom使用node.js IDE的问题,在配置Node.js的IDE了,但setImmediate().re ...
- Node.js Event Loop 的理解 Timers,process.nextTick()
写这篇文章的目的是将自己对该文章的理解做一个记录,官方文档链接The Node.js Event Loop, Timers, and process.nextTick() 文章内容可能有错误理解的地方 ...
- process.nextTick,Promise.then,setTimeout,setImmediate执行顺序
1. 同步代码执行顺序优先级高于异步代码执行顺序优先级: 2. new Promise(fn)中的fn是同步执行: 3. process.nextTick()>Promise.then()> ...
- 解读setTimeout, promise.then, process.nextTick, setImmediate的执行顺序
最近在看<Node.js调试指南>的时候遇到有意思的几道题,是关于setTimeout, promise.then, process.nextTick, setImmediate的执行顺序 ...
- node中定时器, process.nextTick(), setImediate()的区别与联系
1.定时器 setTimeout()和setInterval()与浏览器中的API是一致的,定时器的问题在于,他并非精确的(在容忍范围内).尽管事件循环十分快,但是如果某一次循环占用的时间较多,那么下 ...
- Node.js学习笔记:setImmediate与process.nextTick
通过process.nextTick注册的函数在当前这个事件循环中执行的函数执行完毕后立即执行,相当于把当前的同步代码执行完毕之后,立刻执行所有的通过process.nextTick注册的函数,如果注 ...
随机推荐
- 微信公众平台如何与Web App结合?
Web App简而言之就是为移动平台而优化的网页,它可以表现得和原生应用一样,并且克服了原生应用一些固有的缺点.一般而言Web App最大的入口是浏览器,但现在微信公众平台作为新兴的平台,结合其内置浏 ...
- DevOps Workshop 研发运维一体化(北京第二场) 2016.04.27
北京不亏为首都,人才济济,对微软DevOps解决方案感兴趣的人太多.我们与微软公司临时决定再家一场培训. 我之前在博客中(DevOps Workshop 研发运维一体化第一场(微软亚太研发集团总部)h ...
- 执行js-----Selenium快速入门(十四)
Selenium能够执行js,这使得Selenium拥有更为强大的能力.既然能执行js,那么js能做的事,Selenium应该大部分也能做.这应该得益于JavascriptExecutor这个接口,而 ...
- python寻找list中最大值、最小值并返回其所在位置
c = [-10,-5,0,5,3,10,15,-20,25] print c.index(min(c)) # 返回最小值 print c.index(max(c)) # 返回最大值
- hdoj1072 Nightmare(bfs)
题目大意: 在迷宫中有一个炸弹,过六个单位时间就会爆炸,要你求一个起点到迷宫的终点的最短距离,迷宫中有时间重置器,当你走到这个格子,炸弹的爆炸时间重新置为0,迷宫中标识为墙壁的格子不能走,到达任意一个 ...
- AndroidManifest.xml文件安全探索
本文作者:i春秋签约作家——icq8756c1a2 最近在做一些apk的安全检测,对AndroidManifest.xml文件进行了研究和探讨,介绍AndroidManifest.xml文件的作用和架 ...
- [rejected] master -> master (fetch first)
可以输入: git push -f 可以ok了. 确实是OK了,但是不知道原理,待后来解
- 十分钟用 Node 命令行工具打造 react-cli 脚手架
如果你有以下想法: 每次新开项目需要copy一堆文件/文件夹,太烦!想要快速建立工程 用了vue-cli.react-app,羡慕!想要自己做一个 你只需花十分钟时间,做一个Node命令行工具,打造属 ...
- 2019CVPR《Mask Scoring R-CNN》
题目:<Mask Scoring R-CNN> CVPR 2019 Oral Paper(2017年783篇论文,获得口头报道的有215篇,oral paper很有含金量) 华中科技大学h ...
- 【LeetCode】 617. 合并二叉树
题目 给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠. 你需要将他们合并为一个新的二叉树.合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否 ...