JS异步之宏队列与微队列.md

原理图

异步执行的回调函数有一个共同特点:在合适的时机都会被放到队列里面去。下面来看一些哪些种类的回调函数是放到宏队列,哪些是放到微队列的

宏队列中每一个回调称为宏任务,微队列中的每一个回调称为微任务

  • 宏队列:用来保存待执行的宏任务(回调)

    • dom事件回调
    • ajax回调
    • 定时器回调
  • 微队列:用来保存待执行的微任务(回调)

    • promise回调
    • mutation回调
    setTimeout(() => {
    
        // 会立即放入宏队列
      console.log("timeout callback");
    }, 0);

    Promise.resolve(1).then(
      value => {
    
        // 会立即放入微队列
        console.log('Promise onResolved()', value);
      }
    )

可以看到是下面的promise先执行,settimeout后执行的

多加一个呢??

    setTimeout(() => {
    
        // 会立即放入宏队列
      console.log("timeout callback 1");
    }, 0);
    setTimeout(() => {
    
        // 会立即放入宏队列
      console.log("timeout callback 2");
    }, 0);

    Promise.resolve(1).then(
      value => {
    
        // 会立即放入微队列
        console.log('Promise onResolved1()', value);
      }
    )
    Promise.resolve(2).then(
      value => {
    
        // 会立即放入微队列
        console.log('Promise onResolved2()', value);
      }
    )

可以看到还是promise先执行,settimeout后执行的

JS引擎是单线程执行的,单线程执行就是在某个时间点只能干一件事。也就是说它的基本整体流程分为两步:

  • 先执行完所有的同步代码
  • 再执行队列里面的回调函数

那还有种可能性是:初始化的同步代码还没有执行完,队列里面就有回调函数了。但是队列里面的回调函数不会执行,因为只有一条线路(只有将所有的同步代码执行完之后才能执行队列里面的回调函数

执行队列里面的回调函数时,先执行微队列后执行宏队列

JS执行时会区分这两个队列:

  • JS引擎首先必须先执行所有的初始化同步代码
  • 每次准备取出第一个宏任务执行前,都要将所有的微任务一个一个取出来执行

怎么理解上面这句话呢?代码来看

    setTimeout(() => {
    
        // 会立即放入宏队列
      console.log("timeout callback 1");
      Promise.resolve(3).then(
      value => {
    
        // 会立即放入微队列
        console.log('Promise onResolved3()', value);
      }
    )
    }, 0);
    setTimeout(() => {
    
        // 会立即放入宏队列
      console.log("timeout callback 2");
    }, 0);

    Promise.resolve(1).then(
      value => {
    
        // 会立即放入微队列
        console.log('Promise onResolved1()', value);
      }
    )
    Promise.resolve(2).then(
      value => {
    
        // 会立即放入微队列
        console.log('Promise onResolved2()', value);
      }
    )

说明:

可以看到先执行了Promise onResolved1()Promise onResolved2()这两个微任务,然后去执行宏任务timeout callback 1,这时发现宏任务中包含一个微任务Promise onResolved3(),所以先执行了这个微任务Promise onResolved3()之后,再去执行下一个宏任务timeout callback 2

猜你喜欢

转载自blog.csdn.net/LLLLLLLLLLe/article/details/108053890