这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战
问题
面试官:promise都有经常用,那你能讲讲它的allSettled方法吗?
面试者:这个方法是属于他的静态方法,挂载在Promise上的,他接受一组promise对象,只要这组promise对象状态有一个变了,就会执行它的then方法。
面试官: 你讲的好像是它的race方法。
面试者: 尴尬。。。
promise有几个方法不经常用的话,经常会搞混,今天来总结下它们的区别。
promise
promise实例上的then,catch方法,这几个一般不会混淆。
混淆的主要是实例上的finally方法,静态方法all, race,allSettled,any方法。
实例方法
finally
finally方法不管promise的状态如何,一旦状态由pending变了(比如fulfilled或者rejected),都会执行finally方法。回调函数没有参数返回。执行后返回promise对象。
new Promise((resolve,reject) => {
resolve('resolve')
}).finally(() => {console.log('finally函数被执行了')})
new Promise((resolve,reject) => {
reject('reject')
}).finally(() => {console.log('finally函数被执行了')})
静态方法
all
all方法的参数可选,但是必须是具有iterator接口,一般是数组,然后数组里的每一项是promise对象,如果是其他类型,会调用Promise.resolve转成promise对象。执行all后返回promise对象。
只有当参数里的所有项的状态都变成fulfilled,all返回的promise对象的状态才变成fulfilled,返回值是所有项的返回值组成的数组。
只要参数里有一项变成rejected,all返回的promise对象的状态就变成rejected, 返回值就是那一项的返回值。
Promise.all([1,2,3,4]).then((res) => {
console.log(res) // [1,2,3,4]
})
Promise.all([1,2,Promise.reject(1),4]).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err) // 1
})
race
race方法的参数跟all的一样,需要具有iterator接口,返回的是promise对象。
它和all不同的是:
只要参数里的任意项先改变状态,race的状态就变成它的状态(如果是rejected就是rejected,如果是fulfilled就是fulfilled),后续其他项的状态不会再影响race的状态。然后就执行对应的回调函数(then或者catch等)。回调函数的参数就是那一项的返回值。
Promise.race([Promise.resolve('then'),Promise.reject('reject'),3,4]).then((res) => {
console.log('then:', res)
}).catch((err) => {
console.log('err:',err)
})
// then: then
Promise.race([Promise.reject('reject'),Promise.resolve('then'),3,4]).then((res) => {
console.log('then:', res)
}).catch((err) => {
console.log('err:',err)
})
// err: reject
allSettled
和all和race的传参一样,需要具有iterator接口,返回的是promise对象。
不一样的是,allSettled总是要等到参数里的promise的状态全部发生改变之后,才会执行后面的回调函数,而且不管参数的promise变成fulfilled还是rejected状态,allSettled的状态只会是fulfilled。
Promise.allSettled([Promise.reject('err'),new Promise((resolve, reject) => {
setTimeout(reject.bind(null, 'err'), 2000)
}), 4]).then((res) => {
console.log(res)
// [
// {status: 'rejected', reason: 'err'},
// {status: 'rejected', reason: 'err'},
// {status: 'fulfilled', value: 4}
// ]
})
回调参数如果状态是fulfilled则会有value字段,如果是rejected则会有reason字段。 对应的是allSettled参数的promise对象的返回值。
any
和all和race,allSettled的传参一样,需要具有iterator接口,返回的是promise对象。
不一样的是,any方法的状态是所有参数的promise都变成rejected才会变成rejected,否则只要有一个promise是fulfilled,它的状态就是fulfilled。回调参数就是fulfilled的promise的返回值。
Promise.any([
Promise.reject('err1'),
Promise.reject('err2'),
Promise.reject('err3')
]).catch((err) => {
console.log(err) // AggregateError: All promises were rejected
})
Promise.any([
Promise.reject('err1'),
Promise.resolve('resolve'),
Promise.reject('err2')
]).then((res) => {
console.log(res) // resolve
})