propmise: allSettled()与all()的区别
一、介绍allSettled()
在es6推出的Promise实例中,有一个方法叫allSettled()。通过Promise.allSettled()可以接收一个数组,并且在数组里面的所有实例,全部执行完,再通过then方法或者catch方法,对数组里面的实例进行遍历与操作。
(function(window){ let p1 = new Promise((resolve, reject) => { //这里是通过setTimeout仿作了一个异步背景 setTimeout(()=>{ resolve('p1'); },500) }) let p2 = new Promise((resolve, reject) => { setTimeout(()=>{ resolve('p2'); },1000) }) let p = Promise.allSettled([p1, p2]).then(res=>{ console.log(res); }) })(window)
运行代码后:生成了一个长度为2的一个列表,并且如果是resovle返回的则是一个{status:“fulfilled”,value:“xxx”}的一个对象。然而,如果是reject返回,则是返回一个{reason: “xxx”,status: “rejected”}的对象。
0: status: "fulfilled" value: "p1" __proto__: Object 1: status: "fulfilled" value: "p2" __proto__: Object length: 2 __proto__: Array(0)
二、介绍all()
Promise.all()与allSettled()差不多,all()也是可以接收一个数组,并且进行遍历。
(function(window){ let p1 = new Promise((resolve, reject) => { setTimeout(()=>{ resolve('p1'); },500) }) let p2 = new Promise((resolve, reject) => { setTimeout(()=>{ resolve('p2'); },1000) }) let p = Promise.all([p1, p2]).then(res=>{ console.log(res); }).catch(err => { console.error(err); }) })(window)
代码运行后:则会返回一个长度为2的数组。
(2) ["p1", "p2"]
三、allSettled()与all()的区别
1、看了上面所返回的数据,它们所返回的数据不太一样,all()返回一个直接包裹resolve内容的数组,则allSettled()返回一个包裹着对象的数组。
如果是all()的话,如果有一个Promise对象报错了,则all()无法执行,会报错你的错误,无法获得其他成功的数据。则allSettled()方法是不管有没有报错,把所有的Promise实例的数据都返回回来,放入到一个对象中。如果是resolve的数据则status值为fulfilled,相反则为rejected。
2、Promise.all 会在任何一个请求失败的时候进入失败状态。
由于单一 Promise 进入 rejected 状态便会立即让 Promise.all() 的结果进入 rejected 状态,以至于通过 Promise.all() 进入 rejected 状态时,其中的源 Promise 仍然可能处于 pending 状态,以至于无法获得所有 Promise 完成的时机。
因此,新的 Promise.allSettled() API 被提出,其中 settled 状态的定义是非 pending,即 fulfilled 或者 rejected 中的任一状态。
Promise.allSettled() 静态方法会等待所有源 Promise 进入 fulfilled 或者 rejected 状态,从而确保不会造成时序上的冲突。
原来查看所有请求的状态
function reflect(promise) { return promise.then( (v) => { return { status: 'fulfilled', value: v }; }, (error) => { return { status: 'rejected', reason: error }; } ); } const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.all(promises.map(reflect)); const successfulPromises = results.filter(p => p.status === 'fulfilled')
Promise.allSettled 可以直接返回 无需包装
const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.allSettled(promises); const successfulPromises = results.filter(p => p.status === 'fulfilled');
和Promise.finally结合更好
// We know all API calls have finished. We use finally but allSettled will never reject. Promise.allSettled(requests).finally(() => { console.log('All requests are completed: either failed or succeeded, I don’t care'); removeLoadingIndicator(); });