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

相关文章
|
7月前
|
前端开发
【面试题】吃透Promise?先实现一个再说(包含所有方法)(二)
【面试题】吃透Promise?先实现一个再说(包含所有方法)(二)
|
7月前
|
存储 运维 前端开发
【面试题】吃透Promise?先实现一个再说(包含所有方法)(一)
【面试题】吃透Promise?先实现一个再说(包含所有方法)(一)
|
前端开发
62 # 借用 promise 写成类的方法
62 # 借用 promise 写成类的方法
33 0
|
前端开发
21 # 实现 promise 的 race 方法
21 # 实现 promise 的 race 方法
54 0
|
前端开发
20 # 实现 promise 的 all 方法
20 # 实现 promise 的 all 方法
53 0
|
1月前
|
前端开发 索引
Promise.all() 方法的参数可以是什么类型?
综上所述,`Promise.all()` 方法的参数类型较为灵活,但无论使用哪种类型的可迭代对象作为参数,其核心的异步操作处理逻辑和成功失败的判断机制都是一致的,都是为了方便地处理多个异步操作的并发执行和结果汇总。
|
1月前
|
存储 前端开发
除了 Promise.all(),还有哪些方法可以处理异步并发操作?
在上述示例中,`concurrentPromises` 函数接受一个Promise数组和最大并发数作为参数,通过手动控制并发执行的Promise数量,实现了对异步操作的并发控制,并在所有Promise完成后返回结果数组。
|
21天前
|
前端开发
Promise.allSettled()方法和Promise.race()方法有什么区别?
`Promise.allSettled()` 提供了一种更全面、更详细的方式来处理多个 `Promise`,而 `Promise.race()` 则更强调速度和竞争。我们需要根据具体的需求来选择使用哪种方法。
|
26天前
|
前端开发
`Promise.all()`方法在处理数组形式参数时的执行机制
Promise.all()` 提供了一种方便的方式来同时处理多个异步操作,并在它们都完成后获取到所有的结果,使得我们能够更高效地进行异步任务的组合和处理。
|
26天前
|
前端开发
`Promise.allSettled()`方法与`Promise.all()`方法有何不同?
`Promise.allSettled()` 提供了一种更灵活和全面的方式来处理多个 `Promise`,使得我们能够更好地应对各种异步操作的情况,尤其是需要详细了解每个 `Promise` 结果的场景。