「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
大家好,我是L同学。在上篇文章中,我们总结了Promise的对象方法,包括then、catch和finally。它们都是Promise的原型prototype上的方法。
今天我们来总结一下Promise的类方法,包括resolve、reject、all、allSettled、race、any方法。
resolve方法
Promise.solve的用法相当于new Promise,并且执行resolve操作,将Promise对象状态设置为fulfilled状态。
const promise = Promise.resolve({name: 'haha'})
// 相当于
/* const promise = new Promise((resolve, reject) => {
resolve({name: 'haha'})
}) */
resolve参数
参数是普通值或者对象
const promise = Promise.resolve({name: 'haha'})
参数是Promise
const promise = Promise.resolve(new Promise((resolve, reject) => {
resolve(111)
}))
如果参数是一个Promise对象,Promise.resolve方法原样返回。
const promise1 = new Promise((resolve, reject) => {
resolve(222)
})
const promise2 = Promise.resolve(promise1)
console.log(promise1 === promise2); // true
参数是thenable
const promise = Promise.resolve({
then: function(resolve, reject) {
resolve(11)
}
})
如果传入的是带有一个跟Promise一样的then方法的对象,Promise.resolve会将这个对象作为Promise执行。
Promise.resolve({
then: function(resolve, reject) {
resolve('foo')
}
})
.then(res => {
console.log(res);
})
reject方法
Promise.reject的用法相当于new Promise,并且执行reject操作,将Promise对象状态设置为rejected状态。
const promise = Promise.reject('rejected')
// 相当于
const promise = new Promise((resolve, reject) => {
reject('reject')
})
Promise.reject传入的参数无论是什么类型,都会作为rejected状态的参数传递到catch中。
Promise.reject(new Error('rejected'))
.catch(err => {
console.log(err);
})
Promise.reject('anything')
.catch(err => {
console.log(err);
})
all方法
Promise.all方法将多个Pormise组合形成一个新的Promise。新的Promise状态由这些多个Promise共同决定。 Promise.all方法的返回值也是一个Promise对象,所以后面可以链式调用then方法。
当所有的Promise状态变为fulfilled时,新的Promise状态为fulfilled,并且将所有Promise的返回值组成一个数组。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(111)
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(222)
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(333)
}, 3000)
})
Promise.all([p1, p2, p3, 'aaa']).then(res => {
console.log('res', res);
}).catch(err => {
console.log('err', err);
})
当其中一个Promise状态变为rejected时,新的Promise状态变为rejected,并且将第一个reject的返回值作为参数。
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(222)
reject(222)
}, 2000)
})
此时Promise对象会调用catch方法,将reject值作为catch的参数进行回调。
以下代码我们可以判断p2比p1先执行resolve,因为p1中有延时器。
function p1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p1')
}, 2000)
})
}
function p2() {
return new Promise((resolve,reject) => {
resolve('p2')
})
}
p1().then(res => {
console.log(res);
})
p2().then(res => {
console.log(res);
})
Promise.all接收一个数组作为参数,数组中可以有普通值,可以有Promise对象。数组中值的顺序一定是我们得到结果的顺序。
Promise.all允许我们按照异步代码调用顺序得到异步代码的执行结果。
Promise.all(['a', 'b', p1(), p2(), 'c']).then(res => {
console.log(res);
})
执行结果:
allSettled方法
all方法有个缺陷,当其中一个Promise变为rejected状态时,新的Promise就会立即变成对应的rejected状态。那么对于fulfilled以及处于pending状态的Promise,我们是无法获取对应的结果。
ES11新增了Promsie.allSettled。settled的意思是稳定的。
Promise.allSettled会在所有Promise都有结果(settled),无论是fulfilled,还是rejected,才会有最终的状态。这个Promsie的状态一定是fulfilled。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(111)
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(222)
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(333)
}, 3000)
})
Promise.allSettled([p1, p2, p3]).then(res => {
console.log('res', res);
}).catch(err => {
console.log('err', err);
})
我们看一下打印结果,结果是个数组,包含了各个Promise的结果,该结果是个对象,有该Promise对象的状态和值。
race方法
Promise.race方法会让多个Promise竞争(race),谁先有结果,就使用该Promise的结果。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(111)
}, 3000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(222)
}, 500)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(333)
}, 1000)
})
Promise.race([p1, p2, p3]).then(res => {
console.log('res', res);
}).catch(err => {
console.log('err', err);
})
any方法
Promise.any方法是ES12新增的,和race方法是类似。
它们的区别是any方法会等到一个fulfilled状态,才会决定新Promise的状态。
如果所有的Promise状态都是rejected,那么它会等到所有Promise都变成rejected状态。
如果所有的Promise状态都是rejected,会报一个AggregateError的错误。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(111)
reject(111)
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(222)
reject(222)
}, 500)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(333)
reject(333)
}, 3000)
})
Promise.any([p1, p2, p3]).then(res => {
console.log('res', res);
}).catch(err => {
console.log('err', err);
})
往期文章 👇👇👇