前言:
本篇文章介绍 Promise 对象的Promise.allSettled() 方法,另外的关于 Promise 文章 可以看我的 ES6专栏
promise 实现 Ajax
首先通过 promise 对象实现 Ajax (如下) ,后面 在代码中 会使用到
const getJSON = function(url) {
const promise = new Promise(function(resolve, reject){
const handler = function() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "text";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
Promise.allSettled()
有时候,我们希望等到一组异步操作都结束了,不管每一个操作是成功还是失败,再进行下一步操作。但是,现有的 Promise 方法很难实现这个要求。
Promise.all()
方法只适合所有异步操作都成功的情况,如果有一个操作失败,就无法满足要求。 Promise.all()方法
const urls = [url_1, url_2, url_3];
const requests = urls.map(x => fetch(x));
try {
await Promise.all(requests);
console.log('所有请求都成功。');
} catch {
console.log('至少一个请求失败,其他请求可能还没结束。');
}
上面示例中,Promise.all()
可以确定所有请求都成功了,但是只要有一个请求失败,它就会报错,而不管另外的请求是否结束。
为了解决这个问题,ES2020 引入了 Promise.allSettled()
方法,用来确定一组异步操作是否都结束了(不管成功或失败)。所以,它的名字叫做”Settled“,包含了 ”fulfilled“和 ”rejected“两种情况。
Promise.allSettled()
方法接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled
还是 rejected
),返回的 Promise 对象才会发生状态变更。
const promises = [
getJSON('https://jsonplaceholder.typicode.com/users/1'),
getJSON('https://jsonplaceholder.typicode.com/uses/2'),
getJSON('https://jsonplaceholder.typicode.com/users/3'),
];
await Promise.allSettled(promises);
removeLoadingIndicator();
上面示例中,数组
promises
包含了三个请求,只有等到这三个请求都结束了(不管请求成功还是失败),
removeLoadingIndicator()
才会执行。
该方法返回的新的 Promise 实例,一旦发生状态变更,状态总是 fulfilled
,不会变成rejected
。状态变成 fulfilled
后,它的回调函数会接收到一个数组作为参数,该数组的每个成员对应前面数组的每个 Promise 对象。
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
console.log(results);
});
// [
// { status: 'fulfilled', value: 42 },
// { status: 'rejected', reason: -1 }
// ]
上面代码中,Promise.allSettled()
的返回值 allSettledPromise
,状态只可能变成 fulfilled
。它的回调函数接收到的参数是数组 results
。该数组的每个成员都是一个对象,对应传入 Promise.allSettled()
的数组里面的两个 Promise 对象。
results
的每个成员是一个对象,对象的格式是固定的,对应异步操作的结果。
// 异步操作成功时
{status: 'fulfilled', value: value}
// 异步操作失败时
{status: 'rejected', reason: reason}
成员对象的 status
属性的值只可能是字符串 fulfilled
或字符串 rejected
,用来区分异步操作是成功还是失败。如果是成功(fulfilled
),对象会有 value
属性,如果是失败(rejected
),会有 reason
属性,对应两种状态时前面异步操作的返回值。
下面是返回值的用法例子。
const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ];
const results = await Promise.allSettled(promises);
// 过滤出成功的请求
const successfulPromises = results.filter(p => p.status === 'fulfilled');
// 过滤出失败的请求,并输出原因
const errors = results
.filter(p => p.status === 'rejected')
.map(p => p.reason);
文章如有错误,恳请大家提出问题,本人不胜感激 。 不懂的地方可以评论,我都会一一回复
文章对大家有帮助的话,希望大家能动手点赞鼓励,大家未来一起努力 长路漫漫,道阻且长