ES11 中的 Promise.any 使用教程

阅读时长 6 分钟读完

介绍

Promise.any 是 ES11 新增的 Promise 方法,它接收一个可迭代对象,返回一个 Promise 对象。当该可迭代对象中的任意一个 Promise 状态变为 fulfilled 时,返回的 Promise 对象状态变为 fulfilled。如果可迭代对象中的所有 Promise 都变为 rejected,返回的 Promise 对象状态变为 rejected,并返回所有 Promise 的 rejection 原因。

这个新的 Promise.any 方法很适合在处理多个异步操作时使用。

用途

在之前,为了实现“某个异步操作完成”这个需求,可以通过以下两种方式来达到目的:

  1. 通过 Promise.race 来达到目的。例如:

以上代码会返回先请求成功的数据,如果其中一个请求失败,将调用函数的 catch 方法。

但是,这种方式只返回第一个 resolved / fulfilled 的 Promise,如果你需要在多个异步操作中找到唯一的解决方法,那么 .race() 可能不是最好的选择。

  1. Promise.all 的使用进行修改。例如:

这种方式, 如果其中一个 Promise 被拒绝 (rejected) 而且没有被 Catch 处理, 则 Promise.all 将会被拒绝并且传送第一个 promise 的拒绝原因。因此,由于我们在 .catch (() => null) 方案中处理了所有拒绝,所以数据不会丢失在某些情况下。

这种方法的缺点是,虽然它允许我们列出所有需要解决的 promise 的聚合起来,但在所有 promise 解决之前,我们需要空的数组或 null 作为我们传递到 Promise.all 中的项,在最后收集所有数据时也需要更多的工作。这样做似乎很麻烦,特别是对于更动态的任务集合和反应性增强程序而言。

现在,你可以使用 Promise.any 来解决这个问题,而不必担心毫无成果的模糊查询。

示例

看一个例子,我们假设我们有一个异步任务列表,我们想要在它们中找出第一个完成的异步任务的结果。

在将 Promise 列表作为参数传递给 Promise 之后,通过一个 .then() 块来接收 Promise 的解决方法。传入的第一个解决 Promise 的值将是我们唯一需要的数据,而不是整个 Promise 数组的解决数据。

案例

下面再看一下一个更复杂的情况,我们有很多服务提供商,我们想尝试从其中一个提供商中获取数据,如果其中一个请求成功,我们将使用提供此数据的服务提供商,如果所有尝试都失败了,我们将使用备用服务提供商。

-- -------------------- ---- -------
----- ---------------- - -
  ---------------------------
  ---------------------------
  ---------------------------
--

----- -------------- - -----------------------------

----- ------------ - ----- ----------- ---------- -- -
  ----- -------- - ------------------------ --
    ------------------------------------------------- --
      ----------- - --------------- - -----------------------------------
    -
  --
  --- -
    ----- ------ - ----- ----------------------
    ------ - ------- ---------- ------ --
  - ----- --- -
    ------ - ------- --------- --
  -
--

------------------------------ ------------
  -------- ------- ------ -- -- -
    -- ------- --- ---------- -
      --------------------
    - ---- -- ------- --- ---------- -
      ------------------- ------ -----------
      ------ ------------------------------ -------------
    -
  --
  -------- ------- ------ -- -- -
    -- ------- --- ---------- -
      --------------------
    - ---- -- ------- --- ---------- -
      --------------- ---- ---------
    -
  ---

在此示例中, tryProviders() 函数接收一个服务提供商数组和一个目标 URL。尝试从提供者列表中的每个提供者获取数据,如果有一个提供者成功了,返回成功响应数据。否则,如果所有提供商都没有成功,返回失败响应,尝试备份提供商。

随着我们在 tryProviders() 函数中使用 fetch() 开始异步请求,我们通过 .map() 来创建一个 promise 列表。我们还使用 .then(),使每个 promise 在解决之前将结果转换为 JSON。如果解决结果为 true,我们将结果值传递到后续内容。如果解决结果为错误,则我们使用 Promise.reject() 明确拒绝这个 promise。

上面的代码是一个相对高级的示例,但它说明了如果您的实际问题需要, Promise.any 可以在代替 .race() 或提供多个解决方法上更适用。

总结

ES11 中的 Promise.any 是一个非常有用的新功能。通过这个方法,我们只需要等待一组任务请求的最后结果是否成功或失败,然后我们就可以决定下一步要做什么。

除了更改 .all().race() 代码之外,计划在现有代码中使用 Promise.any() 不会太困难,因为工作方式与现有 Promise 模式相同,并且新的 Promise 的状态仅与其一组 Promise 中的第一个解决起决定作用。

有了 Promise.any,就可以根据我们的需求来选择一组 Promise 提供的所有服务商中的一个,而无需担心 undetermined results 的可能性, 让我们处理来自多个提供者的数据。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64530750968c7c53b077ab0f

纠错
反馈