微信登录

Promise 对象 - Promise 组合 - Promise.race 的应用

Promise 对象 - Promise 组合 - Promise.race 的应用

在 JavaScript 中,Promise 是一种用于处理异步操作的对象,它让我们可以更优雅地处理异步任务,避免了回调地狱的问题。而 Promise.race 作为 Promise 组合的重要方法之一,有着独特的应用场景。本文将深入探讨 Promise.race 的原理、用法以及实际应用。

理解 Promise.race

基本语法

Promise.race 方法接收一个可迭代对象(通常是数组)作为参数,这个数组中的每个元素都应该是一个 Promise 对象。它会返回一个新的 Promise 实例,这个新 Promise 会在数组中的任何一个 Promise 率先解决(resolved)或拒绝(rejected)时,立即以相同的状态和结果进行解决或拒绝。其基本语法如下:

  1. Promise.race(iterable);

工作原理

Promise.race 就像是一场赛跑,数组中的每个 Promise 都是一名选手。一旦有一个选手冲过终点线(即 Promise 被解决或拒绝),比赛就结束了,Promise.race 返回的新 Promise 也会以这个率先完成的 Promise 的状态和结果为准。

示例代码

  1. const promise1 = new Promise((resolve, reject) => {
  2. setTimeout(() => {
  3. resolve('Promise 1 resolved');
  4. }, 1000);
  5. });
  6. const promise2 = new Promise((resolve, reject) => {
  7. setTimeout(() => {
  8. resolve('Promise 2 resolved');
  9. }, 2000);
  10. });
  11. Promise.race([promise1, promise2])
  12. .then((result) => {
  13. console.log(result); // 输出: Promise 1 resolved
  14. })
  15. .catch((error) => {
  16. console.error(error);
  17. });

在这个例子中,promise1 会在 1 秒后解决,而 promise2 会在 2 秒后解决。由于 promise1 率先完成,所以 Promise.race 返回的 Promise 会以 promise1 的解决结果进行解决,最终输出 Promise 1 resolved

Promise.race 的应用场景

1. 设置请求超时

在实际开发中,我们经常会遇到网络请求,但有时候请求可能会因为各种原因(如服务器故障、网络延迟等)而长时间没有响应。这时,我们可以使用 Promise.race 来设置请求超时,避免用户长时间等待。

  1. function fetchWithTimeout(url, timeout) {
  2. const fetchPromise = fetch(url);
  3. const timeoutPromise = new Promise((_, reject) => {
  4. setTimeout(() => {
  5. reject(new Error('Request timed out'));
  6. }, timeout);
  7. });
  8. return Promise.race([fetchPromise, timeoutPromise]);
  9. }
  10. fetchWithTimeout('https://api.example.com/data', 5000)
  11. .then((response) => {
  12. if (response.ok) {
  13. return response.json();
  14. }
  15. throw new Error('Network response was not ok');
  16. })
  17. .then((data) => {
  18. console.log(data);
  19. })
  20. .catch((error) => {
  21. console.error(error);
  22. });

在这个例子中,我们创建了两个 Promise:一个是 fetchPromise 用于发起网络请求,另一个是 timeoutPromise 用于设置超时。使用 Promise.race 将这两个 Promise 组合起来,如果在 5 秒内请求没有完成,timeoutPromise 会率先拒绝,从而触发 catch 块,提示用户请求超时。

2. 竞争加载资源

当我们需要从多个数据源加载相同或相似的资源时,可以使用 Promise.race 来选择最快返回结果的数据源。

  1. const source1 = new Promise((resolve) => {
  2. setTimeout(() => {
  3. resolve('Data from source 1');
  4. }, 2000);
  5. });
  6. const source2 = new Promise((resolve) => {
  7. setTimeout(() => {
  8. resolve('Data from source 2');
  9. }, 1000);
  10. });
  11. Promise.race([source1, source2])
  12. .then((data) => {
  13. console.log(data); // 输出: Data from source 2
  14. })
  15. .catch((error) => {
  16. console.error(error);
  17. });

在这个例子中,我们模拟了从两个不同数据源加载数据的过程。由于 source2 会在 1 秒后返回数据,而 source1 会在 2 秒后返回数据,所以 Promise.race 会选择 source2 的结果。

总结

特性 详情
语法 Promise.race(iterable)
原理 多个 Promise 竞争,率先完成的 Promise 决定 Promise.race 返回 Promise 的状态和结果
应用场景 设置请求超时、竞争加载资源等

Promise.race 为我们处理异步操作提供了一种强大而灵活的方式,通过合理运用它,我们可以优化代码逻辑,提高应用的性能和用户体验。在实际开发中,当我们需要处理多个异步任务并关注最快完成的结果时,不妨考虑使用 Promise.race

Promise 对象 - Promise 组合 - Promise.race 的应用