setTimeout(), nextTick(),setImmediate()区别 ZT~
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
它的执行顺序如下:
Microtasks Macrotasks
任务队列不止一个,还有 microtasks 和 macrotasks
microtasks:
- process.nextTick
- promise
- Object.observe
- MutationObserver
macrotasks:
- setTimeout
- setInterval
- setImmediate
- I/O
- UI渲染
- 一个事件循环(event loop)会有一个或多个任务队列(task queue)
- task queue 就是 macrotask queue
- 每一个 event loop 都有一个 microtask queue
- task queue == macrotask queue != microtask queue
- 一个任务 task 可以放入 macrotask queue 也可以放入 microtask queue 中
理解了这些定义之后,再看执行原理:
事件循环的顺序,决定了JavaScript代码的执行顺序。它从script(整体代码)开始第一次循环。之后全局上下文进入函数调用栈。直到调用栈清空(只剩全局),然后执行所有的micro-task。当所有可执行的micro-task执行完毕之后。循环再次从macro-task开始,找到其中一个任务队列执行完毕,然后再执行所有的micro-task,这样一直循环下去。
还要注意一点:
包裹在一个 script 标签中的js代码也是一个 task 确切说是 macrotask。
结论:
process.nextTick(),效率最高,消费资源小,但会阻塞CPU的后续调用;
setTimeout(),精确度不高,可能有延迟执行的情况发生,且因为动用了红黑树,所以消耗资源大;
setImmediate(),消耗的资源小,也不会造成阻塞,但效率也是最低的。
idea观察者 > IO观察者 > check观察者
process.nextTick > setTimeout > setImmediate
console.log('start')const interval = setInterval(() => { console.log('setInterval') }, 0) setTimeout(() => { console.log('setTimeout 1') Promise.resolve() .then(() => { console.log('promise 3') }) .then(() => { console.log('promise 4') }) .then(() => { setTimeout(() => { console.log('setTimeout 2') Promise.resolve() .then(() => { console.log('promise 5') }) .then(() => { console.log('promise 6') }) .then(() => { clearInterval(interval) }) }, 0) }) }, 0) Promise.resolve() .then(() => { console.log('promise 1') }) .then(() => { console.log('promise 2') })
start promise 1 promise 2 setInterval setTimeout 1 promise 3 promise 4 setInterval setTimeout 2 promise 5 promise 6
转载于:https://www.cnblogs.com/qqxwbtt/p/7825150.html
setTimeout(), nextTick(),setImmediate()区别 ZT~相关推荐
- 细说setTimeout/setImmediate/process.nextTick的区别
node.js中的非IO的异步API提供了四种方法,分别为setTimeOut(),setInterval(),setImmediate()以及process.nextTick(),四种方法实现原理相 ...
- setTimeout和setImmediate以及process.nextTick的区别
<第二届阿里巴巴前端练习生计划线上笔试>考试 setTimeout和setImmediate以及process.nextTick的区别 SetTimeOut setTimeout和setI ...
- 前端碎碎念 之 nextTick, setTimeout 以及 setImmediate 三者的执行顺序
『前端碎碎念』系列会记录我平时看书或者看文章遇到的问题,一般都是比较基础但是容易遗忘的知识点,你也可能会在面试中碰到. 我会查阅一些资料并可能加上自己的理解,来记录这些问题.更多文章请前往我的个人博客 ...
- js setTimeout和setInterval区别
1.区别 2.示例代码 <!DOCTYPE html> <html lang="zh"> <head> <meta charset=&qu ...
- setInterval和setTimeout的使用区别
setTimeout和setInterval的使用 这两个方法都可以用来实现在一个固定时间段之后去执行JavaScript.不过两者各有各的应用场景. 方 法 实际上,setTimeout和setIn ...
- Http和Socket连接区别(ZT)
1.TCP连接 要想明白Socket连接,先要明白TCP连接.手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上 ...
- setTimeOut与 setInterval区别
当调用 windows.setTimeOut("add()",3000); 意味着 3秒之后调用add()方法 调用 window.setIn terval(" ...
- javascript setTimeout 和 setInterval 区别
[setTimeout] setTimeout(表达式,延时时间) 在执行时,是在载入后延迟指定时间后,去执行一次表达式,记住,次数 是一次 用setTimeout实现的自动变化显示随机数的效果: & ...
- setTimeout和setInterval区别,以及定时器的传参功能
setTimeout和setInterval都属性Javascript中的定时器,可以规定延迟时间再执行某个操作,不同的是setTimeout在规定时间后执行完某个操作就停止了,而setInterva ...
- 前端面试问到setTImeout与setInterval区别
基础知识 setTimeout 超时调用,超过时间T,就执行fn setInterval 间歇调用,调用周期t,执行fn 相同点 二者调用后均返回数值ID,可以用来取消. 清除setInterval比 ...
最新文章
- 蓝桥杯四平方和Java_蓝桥杯 四平方和
- python零基础能学吗 知乎-Python零基础学习能学好吗?老男孩Python面授班
- Jenkins 技术篇-jenkins的下载、安装与配置
- runat=server
- 不借助Maven,使用Eclipse创建Hello World级别的Spring项目
- python读excel两列为字典_用python读取Excel并保存字典?一两行代码完成骚操作
- 轻量级文本编辑器,Notepad最佳替代品:Notepad++
- 【动态规划】石子合并
- 浅谈GPRS的几种应用方案
- 前端性能优化经典:javascript防抖节流
- zero to one (2)
- 用计算机探索规律概括,《用计算器探索规律》优秀教学设计
- excel使用教程_如何系统地学习Excel?
- 第四课曲面与曲线方程
- 响应式2022英文企业官网源码,感觉挺有创意的
- 基于netty实现gps jtt808协议接入
- 封装获取非行内样式函数
- 手机APP测试注意点
- 科学计算机 app,App Store 上的“超级计算器-科学计算机”
- 不用编程 实现西门子PLC和罗克韦尔AB PLC的通讯和协议转换