宏队列与微队列的Promise

1,317 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

本文作为本人学习总结之用,以笔记为主,同时分享给大家.
因为个人技术有限,如果有发现错误或存在疑问之处,欢迎指出或指点!不胜感谢!
想要做好promise的面试题首先你得知道宏队列和微队列

JS 异步之宏队列与微队列

我们都知道 Js 是单线程都,但是一些操作就带来了进程阻塞问题。为了解决这个问题,Js 有两种的执行模式同步和异步模式。下面简单了解一下

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

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

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

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

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

    • 每次准备取出第一个宏任务执行前, 都要将所有的微任务一个一个取出来执行

1.png

1.png

看了上面两张图就知道每当执行宏任务之前就得看看是否有微任务,有就先执行当前队列中的所有微任务

其实就是Js 解析完成后,在异步任务中,会先执行完所有的微任务,这里也是很多面试题喜欢考察的。 需要注意的是,新创建的微任务会立即进入微任务队列排队执行,不需要等待下一次轮回。

看一下这个基础的宏队列与微队列的问题:因为每次准备取出第一个宏任务执行前, 都要将所有的微任务一个一个取出来执行 所以这个题目就很简单了

setTimeout(() => { // 会立即放入宏列队
  console.log('宏列队timeout')
}, 0)
Promise.resolve(1).then(
  value => { // 会立即放入微列队
    console.log('微列队Promise', value)
  }
) 
//输出 微列队Promise 1   宏列队timeout

Promise相关面试题

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)
  })
    resolve(2)
  p.then((arg) => {
     console.log(arg)
  })
}))

first().then((arg) => {
   console.log(arg)
})
console.log(4)
//输出为3 7 4 1 2 5
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")
})

//输出为1 7 2 3 8 4 6 5 0
async function async1() {
  console.log('async1 start')
  await async2()
  console.log('async1 end')
}

async function async2() {
  console.log('async2')
}

console.log('script start')

setTimeout(() => {
  console.log('setTimeout')
}, 0)

async1()

new Promise(function (resolve) {
  console.log('promise1')
  resolve()
}).then(function () {
  console.log('promise2')
})
console.log('script end')

/* 
输出: 
  script start
  async1 start
  async2
  promise1
  script end
  async1 end
  promise2
  setTimeout
 */

好的,目前看上面题目比较简单。 有啥问题可以留言。自从我看了大佬的发的一个题目整了我大半天

好戏来了请看:

Promise.resolve().then(() => {
  console.log(0);
  return Promise.resolve(4);
}).then((res) => {
  console.log(res)
})

Promise.resolve().then(() => {
  console.log(1);
}).then(() => {
  console.log(2);
}).then(() => {
  console.log(3);
}).then(() => {
  console.log(5);
}).then(() =>{
  console.log(6);
})

输出为 0、1、2、3、4、5、6