所谓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: '失败' }// ]