• 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")
        })
  • 相关阅读:
    QT:不规则窗口的实现
    Sql Server (错误:7302)
    Qt源码分析之信号和槽机制
    Linux下如何发布Qt程序
    QT程序制作deb包并安装在应用程序菜单
    Another Look at Events(再谈Events)
    Qt全局热键(windows篇)(使用RegisterHotKey和句柄进行注册)
    新浪微博回归平静
    Qt中 QString 和int, char等的“相互”转换,关键是QString.toLocal8Bit().data();
    QT中异形窗口的绘制(winEvent处理WM_NCHITTEST消息)
  • 原文地址:https://www.cnblogs.com/BAHG/p/12921321.html
Copyright © 2020-2023  润新知