• JS异步之宏队列与微队列


    1. 原理图

     2. 说明

    JS 中用来存储待执行回调函数的队列包含 2 个不同特定的列队

    • 宏列队:用来保存待执行的宏任务(回调),比如:定时器回调、DOM 事件回调、ajax 回调

    • 微列队:用来保存待执行的微任务(回调),比如:promise的回调、MutationObserver 的回调

    JS 执行时会区别这 2 个队列

    • JS 引擎首先必须先执行所有的初始化同步任务代码

    • 每次准备取出第一个宏任务执行前, 都要将所有的微任务一个一个取出来执行,也就是优先级比宏任务高,且与微任务所处的代码位置无关

    下面这个例子可以看出 Promise 要先于 setTimeout 执行:

      setTimeout(() => { //立即放入宏队列
          console.log('timeout callback1()')
          Promise.resolve(3).then(
            value => { //立即放入微队列
              console.log('Promise onResolved3()', value)
            }
          )
        }, 0)
    
        setTimeout(() => { //立即放入宏队列
          console.log('timeout callback2()')
        }, 0)
    
        Promise.resolve(1).then(
          value => { //立即放入微队列
            console.log('Promise onResolved1()', value)
            setTimeout(() => {
              console.log('timeout callback3()', value)
            }, 0)
          }
        )
    
        Promise.resolve(2).then(
          value => { //立即放入微队列
            console.log('Promise onResolved2()', value)
          }
        )
    
        // Promise onResolved1() 1
        // Promise onResolved2() 2
        // timeout callback1()
        // Promise onResolved3() 3
        // timeout callback2()
        // timeout callback3() 1

    3. 相关面试题

    代码一:

      // 3 7 4 1 2 5
        /*
        宏: []
        微: []
        */
        const first = () => (new Promise((resolve, reject) => {
          console.log(3)
          let p = new Promise((resolve, reject) => {
            console.log(7)
            setTimeout(() => {
              console.log(5)
              resolve(6) //会被忽略,因为会先执行微队列里的resolve(1),此时状态已经改变过了,且状态只能改变一次
            }, 0)
            resolve(1)
          })
          resolve(2)
          p.then((arg) => {
            console.log(arg)
          })
        }))
    
        first().then((arg) => {
          console.log(arg)
        })
        console.log(4)

    代码二:

      // 1 7 2 3 8 4 6 5 0     
        setTimeout(() => {
          console.log("0")
        }, 0)
        new Promise((resolve, reject) => {
          console.log("1")
          resolve()
        }).then(() => {
          console.log("2")
          new Promise((resolve, reject) => {
            console.log("3")
            resolve()
          }).then(() => {
            console.log("4")
          }).then(() => {
            console.log("5")
          })
        }).then(() => {
          console.log("6")
        })
    
        new Promise((resolve, reject) => {
          console.log("7")
          resolve()
        }).then(() => {
          console.log("8")
        })
  • 相关阅读:
    Spring scope注解
    classpath与clsspath*
    Hadoop 5 Hbase 遇到的问题
    Hadoop 3
    Hadoop 4 MapReduce
    Hadoop 2
    Hadoop 1
    毕业设计---jQuery动态生成的a标签的事件绑定
    毕业设计---json,Struts,ajax以及JQuery简单案例
    基于SSH框架的学生选课质量属性分析
  • 原文地址:https://www.cnblogs.com/BAHG/p/12921321.html
Copyright © 2020-2023  润新知