*微任务: promise.then < process.nextTick(先)
1. 主执行栈队列
2. timer队列: setTimeout/setInterval // 到时间后,将任务加入timer队列;没有到时间,且check队列为空,就切换到poll队列等待
3. poll队列: i/o接口,fs.readFile //如果check队列为空,会在此阶段等待定时器到达
4. check队列: setImmediate

1. 执行顺序说明

node10及之前和node11之后的“微任务队列清空条件”不同:
1)node10及之前的版本,队列切换时才会清空微任务队列
2)node11及之后的版本,每执行一个宏任务就清空微任务队列(同浏览器)

1. node V10(每次切换都清空队列)

1. 清空主执行栈队列

2. 清空微任务队列。

3. 按照timer->poll->check队列执行,只要执行队列切换就清空微任务队列。则主执行栈切换到timer队列,也会先清空微任务队列。

4. 定时器时间到达,清空所有的timer队列。

5. 如果定时器时间未到达,到poll队列,查看check队列是否有任务,如果有,清空。否则,在poll队列等待。

6. 轮训timer队列是否有任务。

2. node V11+ (执行一次宏任务就清空微任务队列)

同浏览器事件环

1. 清空主执行栈队列

2.清空微任务队列

3.按照timer->poll-check队列。如果timer定时器时间不到,进入poll队列执行,然后检查check队列,有任务的话,先执行第一个,然后检查微任务队列,如果有任务则清空,再继续执行check队列的其他任务,每执行一次都要清空微任务队列;否则继续等待,直到定时器到达。

4.如果定时器时间到达,如果timer队列有多个任务,先执行第一个,然后取清空微任务队列,然后继续执行,每执行一个timer中的任务就清空一次微任务队列。

5.再进入poll队列,依timer->poll-check轮训

2. 应用

示例1:

setTimeout(() => {
console.log('timeout')
})
setImmediate(() => {
console.log('immediate')
}) // node命令执行后,先后顺序不一定。根据setTimeout定时器的到达时间快慢。
// 如果setTimout回调函数先进入队列,先执行;否则setImmediate先执行

示例2:

const fs = require('fs');
fs.readFile('1.txt', 'utf-8', function() {
process.nextTick(() => {
console.log('nexttick')
})
setTimeout(() => {
console.log('settimeout')
})
setImmediate(() => {
console.log('setImmediate')
})
})
// 运行结果如下:
nexttick
setImmediate //按照事件环,一定先执行;因为fs是poll队列,poll队列->check队列
settimeout

示例3:

process.nextTick(() => {
console.log('nexttick')
})
setTimeout(() => {
console.log('settimeout1')
})
setTimeout(() => {
console.log('settimeout2')
})
setImmediate(() => {
console.log('setImmediate')
process.nextTick(() => {
console.log('immediate->nexttick')
})
})
const fs = require('fs');
fs.readFile('1.txt', 'utf-8', function() {
process.nextTick(() => {
console.log('fs->nexttick')
})
setTimeout(() => {
console.log('fs->settimeout')
})
setImmediate(() => {
console.log('fs->setImmediate')
})
})
fs.readFile('1.txt', 'utf-8', function() {
process.nextTick(() => {
console.log('fs2->nexttick')
})
setTimeout(() => {
console.log('fs2->settimeout')
})
setImmediate(() => {
console.log('fs2->setImmediate')
})
}) // node V10运行结果如下:
nexttick
settimeout1
settimeout2
fs->nexttick
fs2->nexttick
setimmediate
fs->setImmediate
fs2->setImmediate
immediate->nexttick
fs->settimeout
fs2->settimeout // node V11运行结果如下
nexttick
settimeout1
settimeout2
fs->nexttick
fs2->nexttick
setimmediate
immediate->nexttick
fs->setImmediate
fs2->setImmediate
fs->settimeout
fs2->settimeout
 

最新文章

  1. BZOJ 1984: 月下“毛景树” [树链剖分 边权]
  2. 关于Tomcat在eclipse上的配置
  3. Maven学习笔记(1)之安装Maven
  4. DateTime.Compare用法
  5. CSS 兼容 总结
  6. Java基础之泛型——使用泛型链表类型(TryGenericLinkedList)
  7. SQL Agent Job -&gt;&gt; 通过sys.sysprocesses的program_name字段来定位对应的Job
  8. HD4505小Q系列故事&mdash;&mdash;电梯里的爱情
  9. HashMap的两种遍历方式
  10. Intent常用使用汇总
  11. 进程管理利器supervisor
  12. PAT (Advanced Level) 1101. Quick Sort (25)
  13. [LeetCode] Remove Comments 移除注释
  14. [翻译 EF Core in Action 2.2] 创建应用程序的数据库上下文
  15. mysql 开发进阶篇系列 45 物理备份与恢复(xtrabackup 安装,用户权限,配置)
  16. VC获取操作系统位数
  17. 最大团&amp;优化
  18. java 软件安装
  19. lr自带网站WebTours打不开
  20. Screen 常用命令+VNC 启动停止命令总结

热门文章

  1. RS232标准与TTL/COM小常识
  2. 题解 CF1216A 【Prefixes】
  3. 使用pyinstaller编译python文件
  4. Java常用函数式接口--Supplier接口使用案例
  5. Harbor 批量清理历史镜像
  6. Spring高级进阶:BeanFactoryPostProcessor
  7. vue组件上动态添加和删除属性
  8. vue 鼠标移入移出事件执行多次(尤其ie)
  9. JS中浏览器的数据存储机制
  10. git 打tag标着版本