关于 Promise【基础篇】

250 阅读2分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

之前一直理不清楚promise的用法,这里是一篇比较基础的版本,也是参考了很多大神的文章。而且Promise是面试必考哇!搞清楚,一定要搞清楚!

一些Promise简单的概念

  • Promise存在三个状态:pending(等待态)、fulfilled(成功态)、rejected(失败态)

  • pending为初始态,并可以转化为 fulfilled态 和 reject态

  • 一但转化不可变更状态,且必须有一个不可改变的值/原因

    // resolve 为成功,接收参数value,状态改变为fulfilled,不可再次改变
    new Promise((resolve, reject) => resolve(value)) 
    ​
    // reject 为失败,接收参数reason,状态改变为reject,不可再次改变
    new Promise((resolve, reject) => reject(reason))
    
  • 解决两个问题:

    1. 回调地狱
    2. 解决多个并发请求
  • Promise可以解决异步的问题,但其本身是同步的

  • 如果 executor 报错,直接执行 reject()

用法

构造函数 Promise

接受函数回调,传入两个传参

  • resolve:异步操作成功后的回调函数
  • reject:异步操作失败后的回调函数

方法:all、reject、resolve

原型方法:

  • then:接收两个参数,第一个是resolve回调,第二个是reject回调
  • catch
new Promise((resolve, reject) => {
  // 异步操作返回 resolve(resolveResult) / reject(rejectResult)
})
  .then((resolveResesult) => {
        // resolve
      }, (rejectResult) => {
        // reject
      })
  .catch((err) => {
        // throw err
})

Reject 和 catch 捕获失败的区别

  1. reject:执行“reject”情况的回调,放在then的第二个参数

  2. catch:

    • 执行“reject”情况的回调,相当于then的第二个参数的作用
    • 捕获在执行“resolve”的回调中抛出的异常(代码出错)
new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    const num = Math.ceil(Math.random()*10);
    if (num <= 5) {
      resolve(num);
    }
    else {
      reject('数字太大了!')
    }
  }, 500)
}).then((data) => {
  console.log('resolved', data);
  console.log('resolved catch', eee)
}, (err) => {
  console.log('rejected', err);
}).catch(err => {
  console.log('catch', err)
})
​
// ----- num <=5 -------
// resolved 2
// catch ReferenceError: eeee is not defined// ----- num > 5 -------
// rejected 数字太大了!
new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    const num = Math.ceil(Math.random()*10);
    if (num <= 5) {
      resolve(num);
    }
    else {
      reject('数字太大了!')
    }
  }, 500)
}).then(data => {
  console.log('resolved', data);
  console.log('resolved catch', eee)
}).catch(err => {
  console.log('catch', err)
})
​
// 未给then添加第二个回调时,reject会被catch捕获
// ----- num <=5 -------
// resolved 2
// catch ReferenceError: eeee is not defined// ----- num > 5 -------
// catch 数字太大了!

总结【面试题】:

  1. catch捕获的是什么报错?

new Promise的时候,如果在.then中传了第二个参数捕获了reject的报错,那么.catch捕获的只有resolve抛出的异常;如果.then没有传第二个参数,说明.then中仅处理resolve,那么.catch将捕获reject信息&resolve的异常。

Promise.all

谁跑得慢,以谁为准执行回调。

all接收一个数组参数,里面的值是返回的promise对象。当所有异步操作执行完后执行回调。

应用场景:需要并行执行多个异步,并在一个回调中处理。

Promise.race

谁跑得快,以谁为准执行回调。

应用场景:给某个异步设置超时时间,并在超时之后执行相应的操作。