Promise那些事儿

90 阅读3分钟

Promise是ES6的原生对象,用来解决回调地狱问题。

为什么需要promise?

promise的出现解决了异步操作的回调地狱问题。封装异步操作,获取成功和失败的结果。promise的诞生的使命就是优雅地表示异步回调。

为什么需要进行异步操作?

JS是单线程的,一次只能完成一项任务,这个任务执行完后才会执行下一个任务,所以,它会阻塞其他任务。而异步模式可以一起执行多个任务。
常见的异步模式

  • 定时器
  • 接口调用(前后端交互、promise、fetch、axios)
  • 事件函数

接口调用的方式

js 中常见的接口调用方式,有以下几种:

  • 原生ajax
  • 基于jQuery的ajax
  • Fetch
  • Promise
  • axios

promsie的三种状态

promise有三种状态,分别为pending(初始状态)、fulfilled(成功态)、rejected(失败态)。promise适用于只调用一次的回调函数,需调用多次的回调不要用promise,因为promise的状态不可改变

promise的使用

promise是一个构造函数,所以我们在使用的时候需要new一个promise。它接受函数类型的参数。这个函数类型的参数又接受两个参数,分别是resolve(成功时回调)和reject(失败时回调)

promise的三个实例方法和静态方法

then

支持链式调用,then的执行要依赖上一步的结果。
then接收两个参数,resolve和reject,分别对应成功回调和失败回调。
每一次在then做完处理后,都要return一个promise对象,这样才能在下一次then时接收到数据。

catch

但是如果每一步都写reject就很麻烦,所以就诞生了catch。then可以省略reject方法,直接交给catch去处理。同时catch还可以捕获执行resolve时的异常。在.then的最后.catch,就可以监听以上任一过程的出错,这叫做异常穿透

finally

有时候不论成功还是失败都需要执行一些方法,所以就诞生了finally方法。无论成功还是失败都会执行的方法。

静态方法

为了满足更多的需求,又诞生了6个静态方法,分别是:

  • all():所有任务执行成功则返回成功,有任意一个失败就返回失败。
  • allSettled():所有任务都有结果(无论失败还是成功)了才执行
  • any():任意一个执行成功就执行
  • race():任意一个任务成功或失败了就执行,返回的是第一个执行任务的结果
  • reject():返回一个状态为rejected的promise对象
  • resolve():四种情况:
    1.当参数是一个promise实例,直接返回这个实例;
    2.当参数是一个具有then方法的对象,将这个对象转为promise对象,并立即执行对象的then方法;
    3.当参数是没有then方法的对象或者参数不是对象,状态为resolved新的Promise对象,并将参数传入下一个then; 例:Promise.resolve('Hello world')
    4.不带任何参数,返回一个状态为resolved的Promise对象

async/await(ES7)

async/await是promise的语法糖。 async用于声明异步函数,返回值为一个Promise对象。它以类似同步的方法来写异步方法。await后面一般跟一个promise对象,但也可以是其他值。如果表达式是promise对象,await返回的是promise成功的值。如果表达式是其他值,直接将此值作为await返回值。

await名字寓意

当代码执行到await时,代码就在此处等待不继续执行,直到await拿到Promise对象中resolve的数据,才继续往下执行,这样就保证了代码的执行顺序,而且使异步代码看起来更像同步代码。

注意

  1. await必须写在async后面,但是async后面可以没有await。
  2. 如果await的promise失败了,就会抛出异常,需要通过try...catch捕获处理