Promise.allSettled()使用场景

Promise.allSettled()使用场景

上一节我们介绍了Promise.allSettled()方法的第一种使用场景,今天我们再看看其他使用场景。

调用多个独立的 Web 服务 API

Promise.all() 部分的另一个示例是调用多个 Web 服务 API,您希望所有请求都成功。 如果您不需要所有请求都成功,那么您可以使用 Promise.allSettled() 代替。 回到前面的例子,如果可以显示用户个人资料页面,即使某些数据丢失,然后使用 Promise.allSettled() 而不是 Promise.all() 以避免向用户显示错误。 例如:

const API_BASE = "https://jsonplaceholder.typicode.com";

function fetchUserData(userId) {

  const urls = [
	`${API_BASE}/users/${userId}/posts`,
	`${API_BASE}/users/${userId}/albums`,
	`${API_BASE}/users/${userId}/extras`
  ];

  return Promise.allSettled(urls.map(url => fetch(url)))
    .then(results => results.map(result => result.value));
}

fetchUserData(1).then(responses => {
  return Promise.all(
    responses.map(
      response => {
        if (response?.ok) {
          return response.json();
        }
      }
    )
  );
}).then(([posts, albums, extras]) => {

  // process your data as necessary
  if (posts) {
    console.log("Posts");
    console.log(posts);
  }

  if (albums) {
    console.log("Albums");
    console.log(albums);
  }

  if (extras) {
    console.log("Extras");
    console.log(extras);
  }
  
}).catch(reason => console.error(reason.message));

在这个版本的示例中, fetchUserData() 函数使用 Promise.allSettled() 而不是 Promise.all() 来确保可以忽略rejection。 此示例还调用了第三个端点 /users/{userId}/extras,它不存在并将返回 404(用于演示目的)。一旦所有请求都完成,fulfillment handler将每个结果映射到其 value 属性, 这确保任何rejected的promise都映射到undefined, fulfilled的promise被映射到从 fetch() 返回的响应对象。

因为 response 可能是undefined,所以在检查 ok 属性之前,您需要检查 response 是否为真。 然后读取每个有效响应的 JSON 正文,最后一个fulfillment handler读取该数据。 无法保证每个请求的数据都会存在(在此示例中是undefined),因此您需要在处理之前检查每个值是否存在。

 

等待动画完成

在网页中,元素可以同时以多种不同的方式进行动画处理。 例如,您可以为从页面底部向上的元素位置设置动画,同时还可以设置动画将元素扩大到视图中的宽度和高度。 在这些情况下,等待所有动画完成后再对元素或页面进行下一次修改是很有帮助的。 在他的文章中,构建一个 toast 组件,Adam Argyle 解释了一种跟踪 DOM 元素动画何时完成的基本方法。 为了清楚起见,我在这里重写了代码:

function waitForAnimations(element) {
  return Promise.allSettled(
    element.getAnimations().map(animation => animation.finished)
  );
}

const toasterElement = document.getElementById("toaster");
waitForAnimations(toasterElement)
.then(() => console.log("Toaster is done."));

在这种情况下,您并不真正关心是否有任何动画在此过程中失败,也不关心从动画中接收任何已实现的值,因此 Promise.allSettled() 是比 Promise.all() 更合适的选项 . getAnimations() 方法返回一个动画对象数组,每个对象都有一个finished 属性,其中包含一个promise,该promise 在动画完成时被解析。 通过将这些promise中的每一个传递给 Promise.allSettled(),当所有动画完成时,您将收到通知。 因为 Promise.allSettled() 永远不会返回rejected的promise,所以您可以附加一个fuifillment handler,而不必担心任何未捕获的rejection错误。

版权声明:著作权归作者所有。

thumb_up 0 | star_outline 0 | textsms 0