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

相关文章
|
9月前
|
前端开发
【面试题】吃透Promise?先实现一个再说(包含所有方法)(二)
【面试题】吃透Promise?先实现一个再说(包含所有方法)(二)
|
9月前
|
存储 运维 前端开发
【面试题】吃透Promise?先实现一个再说(包含所有方法)(一)
【面试题】吃透Promise?先实现一个再说(包含所有方法)(一)
|
3月前
|
前端开发 索引
Promise.all() 方法的参数可以是什么类型?
综上所述,`Promise.all()` 方法的参数类型较为灵活,但无论使用哪种类型的可迭代对象作为参数,其核心的异步操作处理逻辑和成功失败的判断机制都是一致的,都是为了方便地处理多个异步操作的并发执行和结果汇总。
|
29天前
|
前端开发 JavaScript
除了使用Polyfill,还有其他解决Promise.allSettled()兼容性问题的方法吗?
除了使用Polyfill,还有其他解决Promise.allSettled()兼容性问题的方法吗?
119 81
|
3月前
|
存储 前端开发
除了 Promise.all(),还有哪些方法可以处理异步并发操作?
在上述示例中,`concurrentPromises` 函数接受一个Promise数组和最大并发数作为参数,通过手动控制并发执行的Promise数量,实现了对异步操作的并发控制,并在所有Promise完成后返回结果数组。
|
29天前
|
前端开发 JavaScript
Promise.allSettled()方法的语法是什么?
Promise.allSettled()方法的语法是什么?
140 79
|
29天前
|
Web App开发 前端开发 JavaScript
Promise.allSettled()方法的兼容性如何?
Promise.allSettled()方法的兼容性如何?
143 75
|
3月前
|
监控 调度
在什么情况下应该使用 Promise.allSettled() 方法?
总的来说,`Promise.allSettled()` 为我们处理多个异步任务提供了一种更灵活、更全面的方式,使我们能够更好地应对各种复杂的情况,确保在获取到所有任务结果的同时,能够进行更有效的后续处理和决策。
|
3月前
|
前端开发
Promise.allSettled()方法和Promise.race()方法有什么区别?
`Promise.allSettled()` 提供了一种更全面、更详细的方式来处理多个 `Promise`,而 `Promise.race()` 则更强调速度和竞争。我们需要根据具体的需求来选择使用哪种方法。
|
3月前
|
前端开发 索引
Promise.all() 方法的参数可以是哪些数据类型?
`Promise.all()` 方法的参数具有很大的灵活性,可以适应多种不同的场景和需求,方便地处理多个异步操作的并发执行和结果汇总。