Promise.race() 的使用注意及解决方案

Promise 是用于异步编程的 JS 对象,它可以解决异步操作的顺序、控制及异常处理等问题。Promise.race() 是 Promise 原型方法之一,它用于同时执行多个 Promise,只要有一个 Promise 状态变更就会执行指定操作。但是,在使用 Promise.race() 时需要注意一些问题,本文将介绍 Promise.race() 的使用注意及解决方案。

注意事项

无法处理多个 Promise 中的错误

使用 Promise.race() 执行多个 Promise 时,如果其中一个 Promise 抛出错误,就会执行 @rejected 状态的操作。但是,如果多个 Promise 同时抛出错误,则只会执行其中一个 @rejected 状态的操作。因此,Promise.race() 无法处理多个 Promise 中的错误,需要开发者自行考虑错误处理的方案。

无法取消未完成的 Promise

Promise.race() 只要有一个 Promise 状态变更就会执行指定操作,它并不会取消未完成的 Promise。如果需要取消未完成的 Promise,可以考虑使用 AbortController 或手动取消 Promise。

时间戳问题

在使用 Promise.race() 时,需要注意时间戳问题。如果多个 Promise 都是通过 setTimeout 或 setInterval 创建的定时器,并且时间戳一样,这些定时器的执行顺序就会影响 Promise.race() 的执行结果。因此,在创建定时器时,应尽量避免使用相同的时间戳。

解决方案

处理多个 Promise 中的错误

处理多个 Promise 中的错误,可以使用 Promise.all() 方法。Promise.all() 会执行所有的 Promise,并将所有 Promise 的返回结果通过数组返回。如果其中一个 Promise 抛出错误,则抛出的错误会被 Promise.all() 捕获,并返回 @rejected 状态的操作。

const promises = [Promise.resolve(1), Promise.reject(2), Promise.resolve(3)];
Promise.all(promises)
  .then((data) => console.log(data)) // 输出 [1,2,3]
  .catch((err) => console.log(err)); // 输出 2

取消未完成的 Promise

为了取消未完成的 Promise,我们可以使用 AbortController。AbortController 是一个定义在浏览器中的 API,它可以中断异步请求或操作,包括 fetch 和 setTimeout 等。使用 AborController,我们可以在运行中的异步操作上调用 abort() 方法来中断操作。

const controller = new AbortController();
const signal = controller.signal;
const promises = [Promise.resolve(1), new Promise((res) => setTimeout(() => res(2)), { signal }), Promise.resolve(3)];
Promise.race(promises)
  .then((data) => console.log(data)) // 输出 1
  .catch((err) => console.log(err)); // 输出 [object AbortError]
controller.abort();

延迟处理函数的执行

为了避免因时间戳问题导致 Promise.race() 的执行结果错误,我们可以使用 Promise.race() 之前的 delay 方法,设置等待一定时间再执行 Promise.race()。

const delay = (ms) => new Promise((r) => setTimeout(r, ms));
const promises = [delay(100).then(() => Promise.resolve(1)), Promise.resolve(2)];
Promise.race(promises)
  .then((data) => console.log(data)) // 输出 2
  .catch((err) => console.log(err));

总结

Promise.race() 可以同时执行多个 Promise,但是在使用 Promise.race() 时需要注意一些问题,比如无法处理多个 Promise 中的错误、无法取消未完成的 Promise、时间戳问题等。对于这些问题,开发者们可以采用不同的解决方案,如使用 Promise.all() 处理多个 Promise 中的错误、使用 AbortController 取消未完成的 Promise,或者延迟处理函数的执行等。这些方案都可以帮助开发者更加合理地运用 Promise.race(),提高异步编程的效率。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a24f33add4f0e0ffa6b236


纠错反馈