【Promise】JS 异步之宏队列与微队列

文章目录

  • [1 原理图](#1 原理图)
  • [2 说明](#2 说明)
  • [3 相关面试题](#3 相关面试题)
    • [3.1 面试题1](#3.1 面试题1)
    • [3.2 面试题2](#3.2 面试题2)
    • [3.3 面试题3](#3.3 面试题3)
    • [3.4 面试题4](#3.4 面试题4)

1 原理图

2 说明

  • JS 中用来存储待执行回调函数的队列包含 2 个不同特定的队列:宏队列和微队列。
  • 宏队列:用来保存待执行的宏任务(回调),比如:定时器回调 / DOM事件回调 / ajax 回调。
  • 微队列:用来保存待执行的微任务(回调),比如:promise的回调 / MutationObserver的回调。
  • JS 执行时会区别这 2 个队列:
    • JS 引擎首先必须先执行所有的初始化同步任务代码。
    • 每次准备取出第一个宏任务执行前,都要将所有的微任务一个一个取出来执行。
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>10_宏队列与微队列</title>
</head>

<body>
  <script>
    setTimeout(() => { //会立即放入宏队列
      console.log('timeout callback1()'); //后1
      Promise.resolve(3).then(
        value => { //会立即放入微队列
          //每次取出宏任务前需要把所有的微任务处理掉
          console.log('Promise onResolved3()', value); //timeout callback2()之前
        }
      )
    }, 0);

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

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

</html>

3 相关面试题

3.1 面试题1

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>11_Promise相关面试题1</title>
</head>

<body>
  <script type="text/javascript">
    setTimeout(() => { //放入宏队列 4
      console.log(1);
    }, 0)
    
    Promise.resolve().then(() => { //放入微队列 2
      console.log(2);
    })
    
    Promise.resolve().then(() => { //放入微队列 3
      console.log(4);
    })
    
    console.log(3); //同步代码 1

    //输出:3 2 4 1
  </script>
</body>

</html>

3.2 面试题2

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>11_Promise相关面试题2</title>
</head>

<body>
  <script type="text/javascript">
    setTimeout(() => { //放入宏队列
      console.log(1);
    }, 0)

    new Promise((resolve) => {
      console.log(2); //同步执行
      resolve();
    }).then(() => { //放入微队列
      console.log(3);
    }).then(() => { //上面是pending状态,将此回调函数先存在callbacks中,3执行后放4
      console.log(4);
    })

    console.log(5); //同步执行

    //输出:2 5 3 4 1

    /**
     * 宏: [1]
     *     []
     * 微: [3]
     *     [4]
     *     []
     */

  </script>
</body>

</html>

3.3 面试题3

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>11_Promise相关面试题3</title>
</head>

<body>
  <script type="text/javascript">
    const first = () => (new Promise((resolve, reject) => {
      console.log(3); //同步

      let p = new Promise((resolve, reject) => {
        console.log(7); //同步
        setTimeout(() => { //放入宏队列
          console.log(5);
          resolve(6);
        }, 0)
        resolve(1); //p成功
      })
      
      resolve(2); //first()成功
      p.then((arg) => { //放入微队列
        console.log(arg); //1
      })
    }))

    first().then((arg) => { //放入微队列
      console.log(arg); //2
    })

    console.log(4); //同步

    //3 7 4 1 2 5
    /**
     * 宏: [5]
     * 微: [1, 2]
     */

  </script>
</body>

</html>

3.4 面试题4

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>11_Promise相关面试题4</title>
</head>

<body>
  <script type="text/javascript">
    setTimeout(() => { //放入宏队列
      console.log("0");
    }, 0)

    new Promise((resolve, reject) => {
      console.log("1"); //立刻执行
      resolve();
    }).then(() => { //放入微队列 return undefined
      console.log("2");
      new Promise((resolve, reject) => {
        console.log("3"); //3
        resolve();
      }).then(() => { //放入微队列
        console.log("4");
      }).then(() => { //.then()执行,内部缓存回调函数,然后外层.then()执行完毕
        console.log("5");
      })
    }).then(() => { //放入微队列
      console.log("6");
    })

    new Promise((resolve, reject) => {
      console.log("7");
      resolve();
    }).then(() => { //放入微队列
      console.log("8");
    })

    //1 7 2 3 8 4 6 5 0

    /**
     * 宏: [0]
     *     []
     * 微: [2对应的回调函数, 8]
     *     [8, 4, 6]
     *     [4, 6]
     *     [6, 5]
     *     [5]
     *     []
     */
  </script>
</body>

</html>
相关推荐
dancing9992 小时前
cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能
前端·javascript·typescript·游戏程序
萌萌哒草头将军3 小时前
🚀🚀🚀Prisma 发布无 Rust 引擎预览版,安装和使用更轻量;支持任何 ORM 连接引擎;支持自动备份...
前端·javascript·vue.js
书语时3 小时前
ES6 Promise 状态机
前端·javascript·es6
拉不动的猪4 小时前
管理不同权限用户的左侧菜单展示以及权限按钮的启用 / 禁用之其中一种解决方案
前端·javascript·面试
西陵4 小时前
前端框架渲染DOM的的方式你知道多少?
前端·javascript·架构
海的诗篇_4 小时前
前端开发面试题总结-JavaScript篇(一)
开发语言·前端·javascript·学习·面试
じ☆ve 清风°4 小时前
理解JavaScript中map和parseInt的陷阱:一个常见的面试题解析
开发语言·javascript·ecmascript
江城开朗的豌豆4 小时前
eval:JavaScript里的双刃剑,用好了封神,用不好封号!
前端·javascript·面试
江城开朗的豌豆5 小时前
JavaScript篇:前端定时器黑科技:不用setInterval照样玩转循环任务
前端·javascript·面试
江城开朗的豌豆5 小时前
JavaScript篇:自定义事件:让你的代码学会'打小报告'
前端·javascript·面试