解释 JavaScript 中的 Promise.allSettled() 和 async-await 吗?

1. Promise.allSettled()

Promise.allSettled() 是 JavaScript ES2020 标准中新增的方法之一。它最主要的作用是接收一个 Promise 数组为输入,并返回一个经过处理的 Promise 数组。

这个新的方法与 Promise.all() 方法有些相似,但是也有不同。下面将会对这两种方法的区别进行解释。

1.1 Promise.all() 方法

Promise.all() 方法接收一个 Promise 数组,并且它会返回一个新的 Promise 对象,但是它的行为则稍有不同。当所有的 Promise 对象都是 resolved(或者说是已经兑现了)时,它会 "resolve",并且返回所有 Promise 对象的结果组成的数组。在所有的 Promise 对象中若有超过一个是 rejected,那么它会返回一个 "rejected" 的 Promise,返回的是第一个 "rejected" 的 Promise 对象的结果。这有时候可能不是我们所期望的结果。

const promises = [

Promise.resolve(1),

Promise.resolve(2),

Promise.reject(3)

];

Promise.all(promises)

.then((results) => {

console.log(results);

})

.catch((error) => {

console.log(error);

});

// Output: 3

1.2 Promise.allSettled() 方法

Promise.allSettled() 方法则是会一直等到所有的 Promise 对象都 "settled",而不仅仅是 "resolved"。当所有的 Promise 对象都解决了,不管它们是 resolved 还是 rejected,它都会 "resolve",并且返回一个由所有的 Promise 对象结果组成的数组。这个新方法返回的 Promise 并不会 "reject",它总是 "resolved",并且在所有的 Promise 对象都结束后返回。

const promises = [

Promise.resolve(1),

Promise.reject(2),

Promise.resolve(3)

];

Promise.allSettled(promises)

.then((results) => {

console.log(results);

});

// Output:

/*

[

{state: 'fulfilled', value: 1},

{state: 'rejected', reason: 2},

{state: 'fulfilled', value: 3}

]

*/

2. async-await

async-await 是 JavaScript 中处理异步函数的一种新方法。它在 ES2017 中被引入,并且被广泛地应用在了 JavaScript 编程中。本质上,async-await 是建立在 Promise 之上的,所以在理解 async-await 之前,有必要了解一下 Promise。

2.1 Promise

Promise 实际上是一个对象,它表示一个异步操作最终会返回一个值 (或者返回一个错误)。一个 Promise 可以进入下面三个状态:

pending (等待): 初始状态,等待着一个 Promise 的返回结果

fulfilled (完成): Promise 已经成功地返回了一个值,可以理解为是 resolved 的状态

rejected (拒绝): Promise 返回了一个错误

以下是 Promise 的一个简单例子:

const promise = new Promise((resolve, reject) => {

setTimeout(() => {

resolve('Hello, World!')

}, 1000);

});

promise.then(result => {

console.log(result);

}); // Output: Hello, World!

2.2 Async-await

async-await 是建立在 Promise 之上的一种异步函数处理方式,它把 promise 的回调地狱问题解决了。async 关键字被放在函数前面,表示这个函数内部可能含有异步操作。await 关键字被放在 Promise 或者 Promise-like 对象前面,表示我们需要等待一个异步操作执行完成后再执行这个函数之后的语句。

async function greeting() {

return 'Hello, World!';

}

async function sayHello() {

const result = await greeting();

console.log(result);

}

sayHello(); // Output: Hello, World!

在这个例子中,我们定义了一个异步函数 greeting 。因为我们用了 async 这个关键词,所以函数的返回值是一个 Promise 对象。在 sayHello 函数中,我们使用了 await 来等待 greeting 函数的 Promise 对象 resolve。

和 promise 相比,async-await 是一个更加好理解、更加直观、代码更加优雅的异步实现方案。在面对异步情况下的 code refactor 时,往往可以优先尝试使用 async-await。

3. 总结

Promise.allSettled() 是 JavaScript ES2020 标准中新增的方法之一,它的作用是接收一个 Promise 数组为输入,并返回一个经过处理的 Promise 数组。和 Promise.all() 的区别在于,Promise.all() 方法只要遇到一个 rejected 的 Promise 就会立即返回,并且返回第一个 rejected 的 Promise 对象包含的错误信息;而 Promise.allSettled() 方法会等待所有 Promise 对象都 settled 之后才会返回一个由所有的 Promise 对象结果组成的数组。这个新方法返回的 Promise 并不会 "reject",它总是 "resolved",并且在所有的 Promise 对象都结束后返回。

async-await 是建立在 Promise 之上的一种异步函数处理方式,它是 Promise 回调地狱的一个解决方案。使用 async-await 的代码可读性更好、更加直观、更加优雅。