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的数据,才继续往下执行,这样就保证了代码的执行顺序,而且使异步代码看起来更像同步代码。
注意
- await必须写在async后面,但是async后面可以没有await。
- 如果await的promise失败了,就会抛出异常,需要通过try...catch捕获处理