Promise 的方法:.all()、.any()、.finally()、.race()

2025-06-10

Promise 的方法:.all()、.any()、.finally()、.race()

在本系列的前几篇文章中,我展示了Promiseresolve和方法,以及如何使用方法从Promise中检索数据。 [ https://dev.to/swarnaliroy94/retrieving-data-from-promise-then-catch-3onk ]rejectPromise.then()Promise.catch()

我们可以使用项目中最常用的方法来简化这个过程Async/Await。不过,在介绍Async/Await之前,我想先让读者熟悉一下 Promise 的其他一些方法。

我将在这篇文章中展示的方法Promise.all()、、& Promise.race()Promise.any()Promise.finally()

那我们开始吧!!

◼️ Promise.all() 方法

👉 该Promise.all()方法接受一个可迭代的对象,例如一个承诺数组作为输入,并返回一个解析为输入承诺的结果数组的承诺。 👉 当所有输入的承诺都已解决或可迭代输入不包含承诺时,返回的承诺将被解决。 👉当输入承诺拒绝或非承诺引发错误时, 它会立即拒绝,并将使用第一个拒绝消息/错误消息拒绝 👉 当涉及许多异步任务时,它通常用于整个代码依赖于成功运行 - 我们希望在继续执行代码之前完成所有这些任务。 👉 此方法聚合多个承诺 的结果



Promise.all() 的实现

🔹 当传递一个空的可迭代对象时,此方法返回的 Promise 将被同步执行。解析后的值将是一个空数组。🔹
当传递一个非空的可迭代对象时,如果所有 Promise都已实现都不是 Promise,则此方法返回的 Promise 将被异步执行。

以下是方法示例Promise.all()👇

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 300, "resolved");
}); //will be resolved after 300ms

const promise2 = 93; //non-promise

const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "resolved2");
}); // will be resolved after 100ms

Promise.all([promise1, promise2, promise3])
  .then((values) => {
    console.log(values);
  })
  .catch((err) => {
    console.log(err);
  });

//expected output: [ 'resolved', 93, 'resolved2' ]
Enter fullscreen mode Exit fullscreen mode

Promise.all() 的拒绝:快速失败行为

Promise.all()显示快速失败行为,即,如果传入的任何元素被拒绝,则 Promise.all() 会异步拒绝,并使用被拒绝的承诺的值

例如,如果我们传入两个在超时后 resolve 的 Promise 和一个立即 throw 的Promise ,那么Promise.all()就会立即 throw 。它不依赖于其他 Promise 是否已经resolve。以下示例就是这么做的!

const pro1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("one"), 1000);
});

const pro2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("two"), 2000);
});

const pro3 = new Promise((resolve, reject) => {
  setTimeout(() => reject("rejected"), 3000);
});

Promise.all([pro1, pro2, pro3])
  .then((values) => {
    console.log(values);
  })
  .catch((error) => {
    console.log(error);
  });

  //expected output: rejected
Enter fullscreen mode Exit fullscreen mode

让我们转到另一种方法Promise.any()

◼️ Promise.any() 方法

👉Promise.any()接受一个可迭代的对象,例如一个承诺数组作为输入。一旦承诺得到履行就会返回一个承诺,并使用该承诺的值来解决
该承诺。👉 如果可迭代的履行中没有承诺(如果所有给定的承诺都被拒绝),则返回的承诺将被拒绝,并出现AggregateError(将各个错误组合在一起)。

Promise.any() 的实现

🔹 与 不同Promise.all(),此方法用于返回第一个满足 的promise。🔹promise完成后立即短路,因此一旦 promise满足,它就不会等待其他 promise完成。🔹 当传递非空可迭代对象时,并且任何 promise 满足或为非 promise,则此方法返回的 promise 将异步满足。

例如,以下代码片段将首先解析QuickyDone 的Promise,因为它在100ms后解析完成,而另一个 Promise 在500ms后解析完成。它不会等待任何其他 Promise 完成,而是立即返回第一个解析完成的 Promise

const SlowlyDone = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "Done slowly");
}); //resolves after 500ms

const QuicklyDone = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "Done quickly");
}); //resolves after 100ms

const Rejection = new Promise((resolve, reject) => {
  setTimeout(reject, 100, "Rejected"); //always rejected
});

Promise.any([SlowlyDone, QuicklyDone, Rejection])
  .then((value) => {
    console.log(value);
    //  QuicklyDone fulfils first
  })
  .catch((err) => {
    console.log(err);
  });

//expected output: Done quickly
Enter fullscreen mode Exit fullscreen mode

Promise.any() 的拒绝

🔹 如果没有 Promise 履行,Promise.any() 会拒绝并抛出 AggregateError 错误。🔹 AggregateError
对象表示需要将多个错误包装在一个错误中时出现的错误。当操作需要报告多个错误时,会抛出该错误。

下面是一个例子👇

const Rejection = new Promise((resolve, reject) => {
  setTimeout(reject, 100, "Rejected"); //always rejected
});

Promise.any([Rejection])
  .catch((err) => {
    console.log(err);
  });

// expected output: "AggregateError: No Promise in Promise.any was resolved"
Enter fullscreen mode Exit fullscreen mode
⭐ 注意,Promise.any() 在node.js 15.0.0中受支持。如果你的 node.js 版本低于此版本,控制台可能会显示TypeError: Promise.any is not a function错误,因此你需要更新版本并重试。

◼️ Promise.prototype.finally()

👉 该finally()方法返回一个Promise
👉 当 Promise完成(无论是解决还是拒绝)时,都会执行此指定的回调函数。
👉 这有助于避免在承诺的 then() 和 catch() 处理程序中重复代码。
👉 如果您要在做出承诺后进行任何处理或清理工作,无论结果如何,finally() 方法都会有所帮助。

以下是此方法的一个简单示例。👇

const addition = (a, b) =>
  new Promise((resolve, reject) => {
    if (typeof a == "number" && typeof b == "number") {
      resolve(a + b);
    } else {
      reject("Not a Number");
    }
  });

addition(10, 5)
  .then((response) => {
    console.log(response);
  })
  .catch((err) => {
    console.log(err);
  })
  .finally(() => {
    console.log("Numbers are added");
  });

  /* expected output: 15
                     Numbers are added */
Enter fullscreen mode Exit fullscreen mode

◼️ Promise.race() 方法

👉只要可迭代对象(例如数组)中的一个承诺通过该承诺的值或原因实现或拒绝,该Promise.race()方法就会返回一个已解决或已拒绝的Promise 。 👉如果传递的可迭代对象为空, 则返回的承诺将永远处于待处理状态 👉如果可迭代对象包含一个或多个非承诺值或已解决的承诺,则将解析为在可迭代对象中找到的第一个值。

Promise.race()

让我们看一个带有 setTimeout 的Promise.race()示例👇

const pro1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("one"), 200);
});

const pro2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("two"), 100);
});

Promise.race([pro1, pro2])
  .then((response) => {
    console.log(response); //output: two
  })
  .catch((err) => {
    console.log(err);
  });

const pro3 = new Promise((resolve, reject) => {
  setTimeout(() => reject("rejected"), 300);
});

const pro4 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("four"), 400);
});

Promise.race([pro3, pro4])
  .then((response) => {
    console.log(response);
  })
  .catch((err) => {
    console.log(err);
  }); //output: rejected

Enter fullscreen mode Exit fullscreen mode

在第一种情况下,pro2(100ms)比pro1(200ms),因此输出显示two。在第二种情况下,pro3(300ms)比pro4(400ms),因此 Promise 被拒绝。所以,Promise.race() 基本上会接受第一个已解决的 Promise。

如果我们采用同样的例子并传递里面的所有承诺Promise.race(),它将返回两个作为输出,因为pro2这种情况下解决的最快的承诺。

const pro1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("one"), 200);
});

const pro2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("two"), 100);
});

const pro3 = new Promise((resolve, reject) => {
  setTimeout(() => reject("rejected"), 300);
});

const pro4 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("four"), 400);
});

Promise.race([pro1, pro2, pro3, pro4])
  .then((response) => {
    console.log(response);
  })
  .catch((err) => {
    console.log(err);
  });

//output: two
Enter fullscreen mode Exit fullscreen mode
在本文中,我们学习了 Promise 的四种重要方法,它们在任何项目中都很常用。另一个重要概念是链式 Promise。我们将在下一篇文章中详细讨论它。
鏂囩珷鏉ユ簮锛�https://dev.to/swarnaliroy94/methods-of-promise-all-any-finally-o2e
PREV
从 Promise 中检索数据:then() 和 catch()
NEXT
时间宝贵,估算是关键:如何估算项目