循环机制(event loop)之宏任务和微任务

一、前言

js任务分为同步任务异步任务异步任务又分为宏任务和微任务,其中异步任务属于耗时的任务。

 

二、宏任务和微任务有哪些?

宏任务:整体代码scriptsetTimeoutsetIntervalsetImmediate(Node.js)i/o操作(输入输出,比如读取文件操作、网络请求)ui render(dom渲染,即更改代码重新渲染dom的过程)异步ajax

微任务:Promise(then、catch、finally)async/awaitprocess.nextTick(Node.js)Object.observe(⽤来实时监测js中对象的变化,已废弃)、 MutationObserver(监听DOM树的变化)

setTimeout

大名鼎鼎的setTimeout无需再多言,大家对他的第一印象就是异步可以延时执行,我们经常这么实现延时3秒执行:

setTimeout(() => {
    console.log('延时3秒');
},3000)

我们还经常遇到setTimeout(fn,0)这样的代码,0秒后执行又是什么意思呢?是不是可以立即执行呢? 答案是不会的,setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行。举例说明:

//代码1
console.log('先执行这里');
setTimeout(() => {
    console.log('执行啦')
},0);

//代码2
console.log('先执行这里');
setTimeout(() => {
    console.log('执行啦')
},3000);

代码1的输出结果是:

先执行这里
执行啦

代码2的输出结果是:

//先执行这里
// ... 3s later
// 执行啦

关于setTimeout要补充的是,即便主线程为空,0毫秒实际上也是达不到的。根据HTML的标准,最低是4毫秒。有兴趣的同学可以自行了解。

Promise与process.nextTick(callback)
  • Promise的定义和功能本文不再赘述,可以学习一下 阮一峰老师的Promise
  • 而process.nextTick(callback)类似node.js版的"setTimeout",在事件循环的下一次循环中调用 callback 回调函数。

看例子:

setTimeout(()=>{
  console.log('setTimeout1')
},0)
let p = new Promise((resolve,reject)=>{
  console.log('Promise1')
  resolve()
})
p.then(()=>{
  console.log('Promise2')    
})

最后输出结果是Promise1,Promise2,setTimeout1

Promise参数中的Promise1是同步执行的 其次是因为Promise是microtasks,会在同步任务执行完后会去清空microtasks queues, 最后清空完微任务再去宏任务队列取值。

Promise.resolve().then(()=>{
  console.log('Promise1')  
  setTimeout(()=>{
    console.log('setTimeout2')
  },0)
})

setTimeout(()=>{
  console.log('setTimeout1')
  Promise.resolve().then(()=>{
    console.log('Promise2')    
  })
},0)

这回是嵌套,大家可以看看,最后输出结果是Promise1,setTimeout1,Promise2,setTimeout2

  • 一开始执行栈的同步任务执行完毕,会去 microtasks queues 找 清空 microtasks queues ,输出Promise1,同时会生成一个异步任务 setTimeout1
  • 去宏任务队列查看此时队列是 setTimeout1 在 setTimeout2 之前,因为setTimeout1执行栈一开始的时候就开始异步执行,所以输出 setTimeout1
  • 在执行setTimeout1时会生成Promise2的一个 microtasks ,放入 microtasks queues 中,接着又是一个循环,去清空 microtasks queues ,输出 Promise2
  • 清空完 microtasks queues ,就又会去宏任务队列取一个,这回取的是 setTimeout2
三、执行顺序

js代码在执行的时候,会先执行同步代码遇到异步宏任务则将异步宏任务放入宏任务队列中遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后,再将异步宏任务从队列中调入主线程执行,一直循环至所有的任务执行完毕(完成一次事件循环EventLoop)。

题目练习:

练习一

setTimeout(function () {
 console.log('1');
})
new Promise(function (resolve) {
 console.log('2');
 resolve();
}).then(function () {
 console.log('3');
})
console.log('4');
//打印顺序 2 4 3 1


练习二

console.log(1);
setTimeout(function () {
  console.log(2);
  let promise = new Promise(function (resolve, reject) {
    console.log(3);
    resolve();
  }).then(function () {
    console.log(4);
  });
}, 1000);
setTimeout(function () {
  console.log(5);
  let promise = new Promise(function (resolve, reject) {
    console.log(6);
    resolve();
  }).then(function () {
    console.log(7);
  });
}, 0);
let promise = new Promise(function (resolve, reject) {
  console.log(8);
  resolve()
}).then(function () {
  console.log(9);
}).then(function () {
  console.log(10)
});
console.log(11);
//执行顺序:1 8 11 9 10 5 6 7 2 3 4

相关推荐

  1. js中的事件循环机制任务任务

    2024-07-22 10:22:02       25 阅读
  2. 任务任务的区别

    2024-07-22 10:22:02       53 阅读
  3. 任务任务

    2024-07-22 10:22:02       40 阅读
  4. 17.EventLoop-IO任务

    2024-07-22 10:22:02       26 阅读
  5. 什么是任务?什么是任务

    2024-07-22 10:22:02       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-22 10:22:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-22 10:22:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-22 10:22:02       45 阅读
  4. Python语言-面向对象

    2024-07-22 10:22:02       55 阅读

热门阅读

  1. 探索半监督学习的力量:半监督目标检测全解析

    2024-07-22 10:22:02       16 阅读
  2. PyTorch张量形状

    2024-07-22 10:22:02       18 阅读
  3. 深度学习落地实战:人脸面部表情识别

    2024-07-22 10:22:02       16 阅读
  4. Python中Selenium 和 keyboard 库的使用

    2024-07-22 10:22:02       13 阅读
  5. 【mybatis 一级缓存】

    2024-07-22 10:22:02       17 阅读
  6. QT表格显示MYSQL数据库源码分析(七)

    2024-07-22 10:22:02       17 阅读
  7. Github 2024-07-22开源项目日报Top10

    2024-07-22 10:22:02       14 阅读
  8. 十六、多任务

    2024-07-22 10:22:02       14 阅读
  9. 目标检测的隐形威胁:对抗攻击的深度解析

    2024-07-22 10:22:02       18 阅读
  10. ASP.NET Core Web深度探讨

    2024-07-22 10:22:02       15 阅读
  11. opencv—常用函数学习_“干货“_13

    2024-07-22 10:22:02       19 阅读