Promise.race() 方法在什么场景下使用?

简介: `Promise.race()` 方法通过其独特的竞争机制,在需要快速获取结果、设置超时控制、实现快速失败以及根据条件动态选择异步操作等场景中,能够提供简洁有效的解决方案,帮助优化异步操作的执行流程和提高系统的响应性能。

Promise.race() 方法在以下几种场景中比较适用:

超时控制

  • 在进行一些可能会耗时较长的异步操作时,为了避免用户长时间等待,可以使用 Promise.race() 来设置一个超时时间。例如,发送一个 AJAX 请求获取数据,但希望在一定时间内如果请求未完成就给出提示并停止等待。
const requestPromise = new Promise((resolve, reject) => {
   
  const xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://example.com/api/data', true);
  xhr.onload = function() {
   
    if (xhr.status === 200) {
   
      resolve(xhr.responseText);
    } else {
   
      reject(new Error('请求失败'));
    }
  };
  xhr.onerror = function() {
   
    reject(new Error('网络错误'));
  };
  xhr.send();
});

const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject('请求超时'), 5000));

Promise.race([requestPromise, timeoutPromise])
.then((result) => {
   
    console.log('请求成功,结果为:', result);
  })
.catch((error) => {
   
    console.log('出错了:', error);
  });

在上述示例中,requestPromise 代表 AJAX 请求,timeoutPromise 会在 5 秒后被拒绝。通过 Promise.race(),如果 requestPromise 在 5 秒内完成,则返回其结果;如果超过 5 秒还未完成,则 Promise.race() 会因为 timeoutPromise 的拒绝而进入 .catch() 块,提示请求超时。

资源竞争

  • 当有多个数据源或多个服务器可以提供相同的数据时,可以使用 Promise.race() 来获取最快返回结果的数据源或服务器的数据。这样可以提高系统的响应速度和资源利用率。
const server1Promise = new Promise((resolve) => setTimeout(() => resolve('服务器1的数据'), 1000));
const server2Promise = new Promise((resolve) => setTimeout(() => resolve('服务器2的数据'), 800));
const server3Promise = new Promise((resolve) => setTimeout(() => resolve('服务器3的数据'), 1200));

Promise.race([server1Promise, server2Promise, server3Promise])
.then((result) => {
   
    console.log('最快获取到的数据为:', result);
  });

在这个例子中,三个服务器分别在不同时间返回数据,Promise.race() 会选择最快返回的服务器的数据作为最终结果,这里会输出 服务器2的数据

快速失败机制

  • 在一些异步操作中,如果其中一个操作失败就可以确定整个流程无需继续进行,可以使用 Promise.race() 来实现快速失败。例如,多个验证操作同时进行,只要有一个验证不通过,就无需等待其他验证结果。
const validation1 = new Promise((resolve, reject) => setTimeout(() => resolve('验证1通过'), 1500));
const validation2 = new Promise((resolve, reject) => setTimeout(() => reject('验证2失败'), 1000));
const validation3 = new Promise((resolve, reject) => setTimeout(() => resolve('验证3通过'), 2000));

Promise.race([validation1, validation2, validation3])
.then((result) => {
   
    console.log('所有验证通过,结果为:', result);
  })
.catch((error) => {
   
    console.log('有验证失败,错误为:', error);
  });

在上述示例中,由于 validation2 在 1000 毫秒时失败,所以 Promise.race() 会立即进入 .catch() 块,无需等待 validation1validation3 的结果,实现了快速失败机制。

动态选择异步操作

  • 根据不同的条件动态地选择执行不同的异步操作,并且只关心最先完成的那个操作的结果。例如,根据用户的权限或配置信息,可能需要从多个不同的接口获取数据,但只需要使用最先返回的数据即可。
const getDataForUser = (userType) => {
   
  if (userType === 'admin') {
   
    return new Promise((resolve) => setTimeout(() => resolve('管理员数据'), 1200));
  } else if (userType === 'user') {
   
    return new Promise((resolve) => setTimeout(() => resolve('普通用户数据'), 1000));
  } else {
   
    return new Promise((resolve) => setTimeout(() => resolve('游客数据'), 1500));
  }
};

const userType = 'user';
const dataPromise = getDataForUser(userType);
const defaultDataPromise = new Promise((resolve) => setTimeout(() => resolve('默认数据'), 800));

Promise.race([dataPromise, defaultDataPromise])
.then((result) => {
   
    console.log('获取到的数据为:', result);
  });

在上述示例中,根据用户类型 userType 动态地获取不同的数据,但同时设置了一个默认数据的获取 Promise。通过 Promise.race(),如果用户数据获取较快,则使用用户数据;如果默认数据获取更快,则使用默认数据。

Promise.race() 方法通过其独特的竞争机制,在需要快速获取结果、设置超时控制、实现快速失败以及根据条件动态选择异步操作等场景中,能够提供简洁有效的解决方案,帮助优化异步操作的执行流程和提高系统的响应性能。

相关文章
|
6月前
|
前端开发
【面试题】吃透Promise?先实现一个再说(包含所有方法)(二)
【面试题】吃透Promise?先实现一个再说(包含所有方法)(二)
|
6月前
|
存储 运维 前端开发
【面试题】吃透Promise?先实现一个再说(包含所有方法)(一)
【面试题】吃透Promise?先实现一个再说(包含所有方法)(一)
|
前端开发
62 # 借用 promise 写成类的方法
62 # 借用 promise 写成类的方法
32 0
|
前端开发
21 # 实现 promise 的 race 方法
21 # 实现 promise 的 race 方法
49 0
|
前端开发
20 # 实现 promise 的 all 方法
20 # 实现 promise 的 all 方法
50 0
|
前端开发
18 # promise 的 finally 方法实现原理
18 # promise 的 finally 方法实现原理
64 0
|
前端开发
7 # promise 的 then 方法
7 # promise 的 then 方法
88 0
|
存储 前端开发
|
9天前
|
前端开发 索引
Promise.all() 方法的参数可以是什么类型?
综上所述,`Promise.all()` 方法的参数类型较为灵活,但无论使用哪种类型的可迭代对象作为参数,其核心的异步操作处理逻辑和成功失败的判断机制都是一致的,都是为了方便地处理多个异步操作的并发执行和结果汇总。
|
12天前
|
存储 前端开发
除了 Promise.all(),还有哪些方法可以处理异步并发操作?
在上述示例中,`concurrentPromises` 函数接受一个Promise数组和最大并发数作为参数,通过手动控制并发执行的Promise数量,实现了对异步操作的并发控制,并在所有Promise完成后返回结果数组。
下一篇
无影云桌面