使用 ES9 的 Promise.allSettled 解决异步请求结果合并问题

在前端开发中,我们常常会遇到需要合并多个异步请求结果的情况。在 ES6 中,Promise.all() 方法已经提供了一种解决方案。但是它在合并多个请求结果时,只有当所有请求的状态都变为 resolved 时,才会返回一个包含所有结果的数组。这就导致了一旦其中有一个请求失败,整个结果就无法得到返回的问题。为了解决这个问题,ES9 引入了 Promise.allSettled() 方法,它可以同时处理 resolved 和 rejected 状态的结果。

Promise.allSettled() 方法

Promise.allSettled() 方法接收一个包含多个 Promise 实例的数组作为参数,并返回一个新的 Promise 实例。它会等待所有的 Promise 实例状态发生变化(resolved 或 rejected),然后返回一个新的数组,包含所有 Promise 实例的状态和值。

下面是 Promise.allSettled() 方法的语法:

Promise.allSettled(iterable);

其中,iterable 是一个可迭代对象,它是一个包含多个 Promise 实例的数组或类数组对象。

示例

假设我们有如下两个异步请求:

const request1 = fetch('https://jsonplaceholder.typicode.com/todos/1');
const request2 = fetch('https://jsonplaceholder.typicode.com/todos/2');

其中,fetch() 方法是浏览器原生的异步请求方法,它返回一个包含请求结果的 Promise 实例。

如果我们使用 Promise.all() 方法合并这两个请求结果,代码如下:

Promise.all([request1, request2])
  .then(([result1, result2]) => {
    console.log(result1, result2);
  })
  .catch(error => {
    console.error(error);
  });

当其中一个请求失败时,程序会进入 catch 块,导致结果无法返回。

而如果使用 Promise.allSettled() 方法合并这两个请求结果,代码如下:

Promise.allSettled([request1, request2])
  .then(results => {
    console.log(results);
  });

无论这两个请求的状态是 resolved 还是 rejected,它们的结果都会被返回,并以对象的方式包含在 results 数组中,如下所示:

[
  { status: "fulfilled", value: {…} },
  { status: "rejected", reason: TypeError: Failed to fetch … }
]

可以看到,这个数组中包含两个元素,第一个元素包含 resolved 状态的请求结果,第二个元素包含 rejected 状态的请求结果。

学习和指导意义

Promise.allSettled() 方法是 ES9 引入的新特性之一,它提供了一种简单的方式来处理异步请求的结果合并。相比于 Promise.all() 方法,它在处理 rejected 状态的结果时更加友好,并且更容易排查程序出现的问题。使用 Promise.allSettled() 方法可以提高代码的可靠性和健壮性,值得前端开发者学习和掌握。

在实际开发中,我们经常会遇到需要同时发起多个异步请求的场景,例如页面的初始化、数据的筛选和查询等。在这些场景中,需要合并异步请求的结果,并对其进行处理。使用 Promise.allSettled() 方法可以简化这一过程,减少了代码复杂度,提高了程序的可读性和可维护性。同时,它也避免了因一处错误导致整个程序无法正常运行的问题,降低了程序出错的风险。

总结

ES9 提供了 Promise.allSettled() 方法来解决异步请求结果的合并问题。与 Promise.all() 方法不同的是,Promise.allSettled() 方法同时处理 resolved 和 rejected 状态的结果,保证了无论请求结果如何,都能够被成功地返回。在实际开发中,使用 Promise.allSettled() 方法可以提高代码的可靠性和健壮性,值得前端开发者学习和掌握。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b113edadd4f0e0ffa62a69