> 文章列表 > Promise详解

Promise详解

Promise详解

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果

1、对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)

2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected

基本用法:

const promise = new Promise(function(resolve, reject) {if (/* 异步操作成功 */){resolve(value);} else {reject(error);}
});
promise.then(res => {/* 异步成功的回调 */复制代码
}).catch(err => {/* 异步失败的回调 */
})

定义在原型对象的方法:

1.Promise.prototype.then()

then()方法是Promise 实例的第一个参数是resolve状态的回调函数

如果then回调方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法:

function promise(params) {  return new Promise((resolve, reject) => {    resolve(`hello~${params}`)  })}promise('xiaoming').then(res => {  console.log(res)  return promise('xiaohong')}).then(res => {  console.log(res)})
// 打印结果:
// hello~xiaoming
// hello~xiaohong
复制代码

2.Promise.prototype.catch() 

catch()方法是Promise 实例的第二个参数是resolve状态或Promise内部代码和then()方法报错的回调函数

直接看代码,catch()会运行的时候

1. 调用reject()确定状态:rejected(已失败)

function promise() {  return new Promise((resolve, reject) => {    // 调用reject()确定状态:rejected(已失败)    reject(new Error('失败了'))  })}promise().catch(err => {  console.log(err)})
// 打印结果: Error: 失败了复制代码

2. 状态为未确定前代码运行中出现出现报错——即使你后面确定了已成功状态

function promise() {  return new Promise((resolve, reject) => {        // 状态为未确定前代码运行中出现出现报错    console.log(a + 1) // a没有声明    resolve() // 即使你后面确定了已成功状态  })}promise().catch(err => {  console.log(err)})
// 打印结果: ReferenceError: a is not defined复制代码

3. then()方法内部代码执行错误——即使你确定了已成功状态且已经运行了then()

function promise() {  return new Promise((resolve, reject) => {// 即使你确定了已成功状态resolve()  })}
// 且已经运行了then()
promise().then(res => {// then()方法内部代码执行错误  console.log(a + 1) // a没有声明}).catch(err => {  console.log(err)})
// 打印结果: ReferenceError: a is not defined
复制代码

3. Promise.prototype.finally()

finally()方法用于指定不管Promise对象最后状态如何,都会执行的操作。它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。该方法是 ES2018 引入标准的。

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···}); // 不管状态如何,都会执行复制代码

4. Promise.all()

Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例

具体的例子

const p = Promise.all([p1, p2, p3]);复制代码

上面代码中,Promise.all()方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例

p的状态由p1、p2、p3决定,分成两种情况。

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数

就是说只要有一个Promise实例为rejected,p的状态就变成rejected

5.Promise.race()

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例

const p = Promise.race([p1, p2, p3]);复制代码

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

下面代码,第二个Promise先确定状态为reject,所以p的状态也会为reject

const p = Promise.race([  new Promise((resolve, reject) => {    setTimeout(() => resolve('成功'), 2000)  }),  new Promise((resolve, reject) => {    setTimeout(() => reject(new Error('失败')), 1000)  })]).then(res => {  console.log(res)})
// 报错: Uncaught (in promise) Error: 失败复制代码

6. Promise.allSettled()

Promise.allSettled()方法同样接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束。该方法由 ES2020 引入。

具体的例子

const p = Promise.allSettled([  new Promise((resolve, reject) => {    resolve('成功')  }),  new Promise((resolve, reject) => {    reject('失败')  })]).then(res => {  console.log(res)})
// [//    { status: 'fulfilled', value: '成功' },//    { status: 'rejected', reason: '失败' }// ]