Skip to content
扫码开始移动端阅读

Promise的使用与方法

1468
需要≈
7.34
分钟
JavaScript

Promise的使用与方法

什么是Promise

Promise是一个类,可以翻译成承诺、许诺、期约...

Executor

Executor是创建Promise对象时传入的回调函数,这个回调函数会立即执行,并且传入两个参数

通常会在 Executor中确定Promise的状态:pendingfulfileed(resolved)、rejected

●通过resolve,可以兑现Promise的状态,由 pending 变为 fulfilled 也可以称之为 resolved

○当调用resolve回调函数时,会执行Promise对象的then方法传入的回调函数

●通过reject,可以拒绝Promise的状态,由 pending 变为 rejected

○当调用reject回调函数时,会执行Promise对象的catch方法传入的回调函数

一旦状态被确定下来,Promise 的状态就会被锁死,该状态是不可更改的。如果同时 resolve 和 reject 看谁先调用决定状态

resolve传入不同值的区别

  1. 一个普通的值或者对象,那么这个值会作为then回调的参数
  2. Promise对象,那么当前Promise状态会由传入的Promise决定
  3. thenable对象,会执行该对象then方法,由该对象then调用结果决定Promise状态

then 方法

then方法是Promise对象上的方法,需要通过new Promise创建实例对象调用

它其实是放在Promise的原型上的 Promise.prototype.then,new 操作符会将创建的实例对象的__proto__指向了构造函数的prototype,all方法是类方法,直接通过Promise.all调用

  1. 接收两个参数

then方法接受两个参数:fulfilled(resolved)的回调函数,当状态变成fulfilled(resolved)时会回调的函数;rejected的回调函数,当状态变成rejected时会回调的函数;

  1. 多次调用

一个Promise的then方法是可以被多次调用的:每次调用我们都可以传入对应的fulfilled(resolved)回调,当Promise的状态变成fulfilled(resolved)时,这些回调都会被执行

  1. 返回值

then方法本身是有返回值的,它返回的是一个Promise,这个Promise的状态有如下变化

●当then方法中的回调函数本身在执行的时候,那么它处于pending状态

●当then方法中的回调函数返回一个结果时,那么它处于fulfilled(resolved)状态,并且将结果作为resolve的参数,参数情况同三、resolve传入不同值的区别

●当then方法抛出一个异常时,那么它处于rejected状态

要注意的是,then的连续链式调用,后一个.then对应的是前一个.then返回的Promise,而非最开始的Promise

catch 方法

catch方法也是Promise对象上的方法,同then原理

  1. 多次调用

一个Promise的catch方法是可以被多次调用的,每次调用我们都可以传入对应的reject回调,当Promise的状态变成rejected时,这些回调函数都会被执行

  1. 返回值

事实上,catch方法也是会返回一个Promise对象,所以在catch方法后面,我们可以继续调用then方法和catch方法,原理同then方法返回值

finally 方法

finally是在ES9(ES2018)中新增的一个特性:表示无论Promise对象无论变成fulfilled(resolved)还是rejected状态,最终都会被执行的代码;finally方法是不接收参数的,因为无论前面是fulfilled(resolved)状态,还是rejected状态,它都会执行。

resolve 方法

前面的then、catch、finally方法都属于Promise的实例方法,都是存放在Promise的prototype上的;除此之外,还有Promise的类方法,我们可以直接通过类方法来完成Promise的resolve

reject 方法

同resolve方法

all 方法

all方法也是Promise的类方法之一,它的作用是将多个Promise包裹在一起,形成一个新的Promise;新的Promise状态由包裹的所有Promise共同决定:

●当所有的Promise状态变成fulfilled(resolved)状态时,新的Promise的状态为fulfilled(resolved),并且会将所有Promise的返回值组成一个数组

●当有一个Promise的状态为rejected时,新的Promise的状态为rejected,并且将第一个reject的返回值作为参数

allSettled 方法

在all方法中,我们发现有一个缺陷:当有其中一个Promise变成reject状态时,新Promise就会立即变成对应的rejected状态;那么对于resolved的,以及依然处于pending状态的Promise,我们是获取不到对应的结果的。所以在ES11(ES2020)中,添加了新的API Promise.allSettled来解决这个缺陷

注意,allSettled的结果一定是fulfilled,所以结果会在.then中输出

race 方法

当我们需要执行多个Promise,如果有一个Promise有了结果,我们就希望决定最终新Promise的状态,那么可以使用race方法;prace是竞技、竞赛的意思,表示多个Promise相互竞争,谁先有结果,那么就使用谁的结果。

JavaScript
const p1 = new Promise((resolve) => { 
  setTimeout(()=>{
    resolve(1)
  },1000)
})
const p2 = new Promise((resolve) => { 
  setTimeout(()=>{
    resolve(2)
  },500)
})
const p3 = new Promise((resolve) => { 
  setTimeout(()=>{
    resolve(3)
  },1500)
})
Promise.race([p1,p2,p3]).then(res => {
  console.log(res)  // 2
}).catch(err => {
  console.log(err) // 不执行
})

any 方法

any方法是ES12中新增的方法,和race方法是类似的;

●any方法会等到一个fulfilled(resolved)状态,才会决定新Promise的状态;

注意,当等到fulfilled(resolved)状态后,便不再往后输出

JavaScript
const p1 = Promise.resolve(1);

const p2 = Promise.reject(2);

const p3 = Promise.resolve(3);

Promise.any([p1,p2,p3]).then(res => {
  console.log(res)  // 1(停止,状态不再变更)
}).catch(err => {
  console.log(err) // 不执行
})

// reject先行

const p11 = Promise.reject(1);

const p22 = Promise.reject(2);

const p33 = Promise.resolve(3);

Promise.any([p11,p22,p33]).then(res => {

  console.log(res)  // 等到 3

}).catch(err => {

  console.log(err) // 不执行

})

●如果所有的Promise都是reject,那么也会等到所有的Promise都变成rejected状态,并报错AggregateError

JavaScript
const p1 = Promise.reject(1);

const p2 = Promise.reject(2);

const p3 = Promise.reject(3);

Promise.any([p1,p2,p3]).then(res => {

  console.log(res)  // 不执行

}).catch(err => {

  console.log(err) // AggregateError: All promises were rejected

})

上次更新: