什么是promise
Promise
是异步编程的一种解决方案,比起传统的回调,更加合理和更加强大。
状态
promise
对象有三种状态:pending
(进行中),fulfilled
(已成功),rejected
(已失败)。
特点
对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态。
一旦状态改变(从pending
变为fulfilled
或从pending
变为rejected
),就不会再变,任何时候都可以得到这个结果。
promise
整个流程如图:
用法
Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
const promise = new Promise(function(resolve, reject) {...});
resolve
函数的作用是,将Promise
对象的状态从“未完成”变为“成功”。
reject
函数的作用是,将Promise
对象的状态从“未完成”变为“失败”。
实例方法
then()
catch()
finally() then
是实例状态发生改变时的回调函数,第一个参数是resolved
状态的回调函数,第二个参数是rejected
状态的回调函数。返回的是一个新的Promise
实例,也就是promise
能链式书写的原因。
catch()
方法是.then(null, rejection)
或.then(undefined, rejection)
的别名,用于指定发生错误时的回调函数。Promise
对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止,但不会传递到外层代码。catch()
方法之中,还能再抛出错误,通过后面catch
方法捕获到。
finally()
方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
构造函数方法
all()
race()
allSettled()
resolve()
reject()
try() Promise.all()
方法用于将多个 Promise
实例,包装成一个新的 Promise
实例。
const p = Promise.all([p1, p2, p3]);
接受一个数组(迭代对象)作为参数,数组成员都应为Promise
实例。
实例p
的状态由p1
、p2
、p3
决定,分为两种:
只有p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数
只要p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数 如果作为参数的 Promise
实例,自己定义了catch
方法,那么它一旦被rejected
,并不会触发Promise.all()
的catch
方法
const p1 = new Promise((resolve, reject) => {resolve('hello');}).then(result => result).catch(e => e);
const p2 = new Promise((resolve, reject) => { throw new Error('报错了'); }) .then(result => result) .catch(e => e);
Promise.all([p1, p2]) .then(result => console.log(result)) .catch(e => console.log(e)); // ["hello", Error: 报错了]
`Promise.race()`方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。只要`p1`、`p2`、`p3`之中有一个实例率先改变状态,`p`的状态就跟着改变。率先改变的 Promise 实例的返回值则传递给`p`的回调函数。`Promise.allSettled()`方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例只有等到所有这些参数实例都返回结果,不管是`fulfilled`还是`rejected`,包装实例才会结束。
const promises = [ fetch('/api-1'), fetch('/api-2'), fetch('/api-3'), ];
await Promise.allSettled(promises); removeLoadingIndicator();
`resolve()`将现有对象转为 `Promise`对象。` reject()`方法也会返回一个新的 Promise 实例,该实例的状态为`rejected`。`reject()`方法的参数,会原封不动地变成后续方法的参数。### `promise`的优缺点#### 优点1. 解决回调地狱问题,链式操作使代码变得扁平,降低了编码难度。进行一些相互间有依赖关系的异步操作时,后一个的请求需要上一次请求的返回结果。以往的方法只能 `callback` 层层嵌套,但嵌套层数过多的话就会有 `callback hell` 问题,可读性和维护性都很差。2. 更好地进行错误捕获。多重嵌套 `callback`可能会造成无法捕获异常或异常捕获不可控。`promises` 通过 `reject` 方法把 `Promise` 的状态置为 `rejected`,这样我们在 `then` 中就能捕捉到,然后执行“失败”情况的回调。#### 缺点1. 无法取消Promise,一旦新建它就会立即执行,无法中途取消。`axios`中可用`cancelToken`来取消。2. 如果不设置回调函数,promise内部抛出的错误,不会反应到外部。3. 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。原文:https://juejin.cn/post/7097490541994049566