45道Promise题记录

75 阅读3分钟

复习Promise相关的面试题时,刷到了一个文章【建议星星】要就来45道Promise面试题一次爽到底(1.1w字用心整理) 本文是我看完之后的笔记。
异步相关的问题,基础知识是事件循环(Event Loop)。在分析代码的时候,执行栈、微任务队列、宏任务队列,这三个队列要确定好。

1.Promise new 实例化的参数函数,是立即执行的

let P = new Promise((resolve, reject) => {
  // 立即执行
  console.log("立即执行")
})

2. 实例化出来的p对象的状态

let P = new Promise((resolve, reject) => {
  resolve() // p的状态就是 fulfilled 成功
  reject() // p的状态就是 rejected 失败

  // 如果没有执行 resolve() 和 reject() 的话 p的状态就是 pending状态
})

// 注意链式操作的时候 p1的值是 then 的return值。
const p1 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('resolve3');
    console.log('timer1') // 3
  }, 0)
  resolve('resovle1');
  resolve('resolve2');
}).then(res => {
  console.log(res) // 1 resovle1
  setTimeout(() => {
    console.log(p1) // 4 fulfilled  resovle1
    // 这里判断错了,因为 这个then 没有 return 值
  }, 1000)
}).finally(res => {
  console.log('finally', res) // 2 finally undefined
  return 1
})

3. return new Promise() 是否执行

    let p = function() {
      return new Promise(() => {})
    }

    p().then(() => {}) // 只有在P函数执行的地方,才会执行Promise实例化

4. setTimeout 的执行会放在宏任务队列,Promise().then().catch() 是放在微任务队列

比如有宏任务事件1,宏任务事件2, 如果在宏任务事件1里面又添加了一个微任务1,那么微任务1比宏任务2先执行 juejin.cn/post/684490…

  1. 如果返回的 Promise 是自己的话,就会形成一个嵌套,会报错的

     const promise = Promise.resolve().then(() => {
       return promise;
     })
     // promise.catch(console.err)
    

6.then 和 catch 的参数期望是 fn ,如果不是的话发生值穿透将 resove() 值传递到最后一个 then里面

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log) // 1

7..all([]) 可以并行执行多个异步任务。

//一组异步任务,如果有一个异常就不会进入 then()。
//catch 会捕获最先跑出来的reject()
Promise.all([runAsync(1), runReject(4), runAsync(3), runReject(2)])

8. await fn(); fn()函数会立即执行,之后代码的执行就放在了,微任务队列中。之后的代码会阻塞。

  1. await new Promise((resolve, reject) => {}) // 如果没有状态的话。 await 后面的代码是不会执行的。如果 new Promise(...) 并不会阻塞后面的代码执行

     // 不会阻塞
     async function async1() {
       console.log("async1 start");
       new Promise((resolve, reject) => {
         console.log('promise')
       })
       console.log("async1 end");
       return '1'
     }
     async1().then((res) => {
       console.log(res)
     })
    
     // 会阻塞
     async function async1 () {
       console.log('async1 start');
       await new Promise(resolve => {
         console.log('promise1')
       })
       console.log('async1 success');
       return 'async1 end'
     }
     console.log('srcipt start')
     async1().then(res => console.log(res))
     console.log('srcipt end')
     
    

10.如果在async函数中抛出了错误,则终止错误结果,不会继续向下执行。

async function async1 () {
  await async2();
  console.log('async1');
  return 'async1 success'
}
async function async2 () {
  return new Promise((resolve, reject) => {
    console.log('async2')
    reject('error')
  })
}
async1().then(res => console.log(res))

11.finally 在 finally2之后 .then() 和 .finally() 会返回一个promise,这种链式调用,就相当于把链式之后的代码放进微任务列表中。

Promise.resolve('1')
  .then(res => {
    console.log(res)
  })
  .finally(() => {
    console.log('finally')
  })

Promise.resolve('2')
  .then(res => {
    console.log('finally2后面的then函数', res)
  })
  .finally(() => {
    console.log('finally2')
        return '我是finally2返回的值'
  })

//1
//finally2后面的then函数 2
//finally
//finally2