一道经典的宏任务和微任务题目(javascript)

  • 事件循环有两种类型的任务:宏任务(macrotasks)和微任务(microtasks)。

宏任务常见的有:脚本、setTimeout、setInterval等,

微任务常见的有:Promise.then、MutationObserver等。

事件循环的算法大致如下:

  1. 1、从宏任务队列中取出并执行最旧的任务(例如“脚本”)。
  2. 2、执行所有微任务:当微任务队列不为空时,取出并执行最旧的微任务。
  3. 3、如果有任何变化,则渲染页面。
  4. 4、重复以上步骤直到宏任务队列为空。

提前小知识:

  1.  setTimeout()函数1用于在指定的毫秒数后执行一个回调函数,但不会阻塞后续代码的执行。
  2.  Promise对象2用于表示一个异步操作的最终状态(完成或失败),以及该操作的结果值。
  3.  then()方法2用于在Promise对象状态变为fulfilled时,执行一个回调函数,并返回一个新的Promise对象。

了解这些基本知识后看这道题就简单多了: 

  setTimeout(function(){
    console.log(1);
  },100);
  new Promise(function(resolve){
    console.log(2);
    resolve();
    console.log(3);
  }).then(function(){
    console.log(4);
    new Promise((resolve,reject)=>{
      console.log(5);
      setTimeout(()=>{
        console.log(6);
      },10);
    })
  })
  console.log(7);
  console.log(8);

可以先自己结合上诉知识推理一下,输出结果是什么?

、、

、、

、、

、、

、、

输出结果:2 3 7 8 4 5 6 1

怎么样 做对了吗?

下面我进行一个保姆级的详细分析:

1、首先创建一个setTimeout()函数,指定在100ms后输出1,但不会立即执行,而是将其放入任务队列中等待调度。

2、创建一个Promise对象,并立即执行其构造函数中的同步代码,即输出2,此时将状态修改为fulfilled,并输出3

3、此时调用then方法,在Promise状态改为fulfilled时,执行一个回调函数,这个回调函数同样不会立即执行,而是将其放入微任务队列中等待调度。

4、然后继续执行同步代码,即输出7和8。

5、此时同步代码已经执行完,开始检查微任务队列(微任务队列优先级高于任务队列)是否有待执行的任务,发现有一个then方法,则执行它,输出4,并创建一个新的Promise对象,则立即执行其构造函数中的同步代码,输出5,同样将其状态改为fulfilled。

6、此时微任务里面还有一个宏任务setTimeout,因此再创建一个setTimeout()函数,10ms后输出6,并将其压入宏任务队列。

7、现在所有微任务都执行完了,宏任务队列里面有两个setTimeout函数,一个100ms,一个10ms,按照顺序执行,先执行100ms的setTimeout函数,再执行10ms的setTimeout函数,因此先输出时间短的输出6,再输出1。

(这里按照时间长短决定输出结果,如果两个函数都是100ms,则按顺序执行,先输出1,再输出6)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值