引言
Promise 是 JavaScript 中异步编程的一种方式,它有很多的静态方法,其中之一就是 Promise.race()。Promise.race() 接受一个可迭代对象,返回一个新的 Promise 对象,该对象在第一个解决或拒绝的 Promise 时解决或拒绝。
但是,当多次调用 Promise.race() 时,它可能不会像我们想象的那样运行。本文将介绍多次调用 Promise.race() 的情况,并提供一些解决方案。
多次调用 Promise.race() 的问题
当我们多次调用 Promise.race() 时,只有第一个完成的 Promise 才会被解决或拒绝。其余 Promise 将被忽略,这可能不是我们想要的结果。
让我们看一下以下示例代码:
-- -------------------- ---- ------- ----- ---- - -------------- --- --------------- -- ------------- -- ------------- ------ --- --------------- -- ------------- -- ------------- ------- --- --------------- -- ------------- -- ------------- ------ --- -------------- -- - ------------------ -------------- -- - --------------------- --- ------------- -- - -------------- --- --------------- -- ------------- -- ------------- ------ --- ----------------- ------- -- ------------- -- ---------- ------------ ------ --- --------------- -- ------------- -- ------------- ----- ------------ -- - ------------------ -------------- -- - --------------------- --- -- -----
这个代码片段中我们先定义了一个 Promise.race(),让它在 0.5s 后解决为 'A'、在 1s 后解决为 'B'、在 1.5s 后解决为 'C'。然后,我们在 setTimeout() 中异步调用另一个 Promise.race(),让它在 0.1s 后解决为 'D'、在 0.4s 后拒绝为 'E'、在 0.6s 后解决为 'F'。
当我们运行代码时,输出结果为:
A
可以看到,'D'、'E' 和 'F' 的状态都被忽略了。这不是我们想要的结果,我们需要让每个 Promise 都被正确处理。
解决方案
有多种解决方案可以解决这个问题。
1. 将 Promise.race() 封装为类
我们可以封装一个类来处理多次调用 Promise.race() 的问题。
-- -------------------- ---- ------- ----- ---- - --------------------- - -- -------------------------- - ----- --- --------------------- -------- -- ----- -- ----------- - --------- - ----------------------- --------- - ------ - ------------- ------- - -- ----------- - ------ ----------------------- -------- - --------- - ----- ----------------------- -------- - ------------- - -- ----------- - ------ ------------------------ - --------- - ----- ------------------------ - -
我们在这个类中封装了 Promise.race()。当第一个 Promise 完成时,我们通过判断 this.done 的值是否为 true 来判断该 Promise 是否已经被处理。如果是,则使用新创建的 Promise 对象。否则,我们将在当前对象上调用 then() 或 catch()。
可以看到,在上面的示例代码中,我们只需将 Promise.race() 替换为 Race 就可以了。
-- -------------------- ---- ------- ----- ---- - --- ------ --- --------------- -- ------------- -- ------------- ------ --- --------------- -- ------------- -- ------------- ------- --- --------------- -- ------------- -- ------------- ------ --- -------------- -- - ------------------ -------------- -- - --------------------- --- ------------- -- - ----- ----- - --- ------ --- --------------- -- ------------- -- ------------- ------ --- ----------------- ------- -- ------------- -- ---------- ------------ ------ --- --------------- -- ------------- -- ------------- ----- --- --------------- -- - ------------------ -------------- -- - --------------------- --- -- -----
当我们运行代码时,输出结果为:
A E
可以看到,我们现在正确处理了所有的 Promise。
2. 使用 Promise.all()
另一个解决方案是使用 Promise.all()。Promise.all() 接受一个可迭代对象,返回一个新的 Promise 对象,该对象在所有 Promise 都解决后解决。因为 Promise.all() 返回的 Promise 对象当所有 Promise 都已完成时才会完成,所以可以确保所有 Promise 都被处理。
-- -------------------- ---- ------- ----- -------- - - -------------- --- --------------- -- ------------- -- ------------- ------ --- --------------- -- ------------- -- ------------- ------- --- --------------- -- ------------- -- ------------- ------ --- -------------- --- --------------- -- ------------- -- ------------- ------ --- ----------------- ------- -- ------------- -- ---------- ------------ ------ --- --------------- -- ------------- -- ------------- ----- -- -- --------------------- ---------- -- - ------------------ -- ------------ -- - --------------------- ---
当我们运行代码时,输出结果为:
['A', 'F']
可以看到,我们成功处理了所有的 Promise。
结论
当我们多次调用 Promise.race() 时,只有第一个完成的 Promise 才会被解决或拒绝。其余 Promise 将被忽略,这可能不是我们想要的结果。我们可以封装一个类来解决这个问题,也可以使用 Promise.all()。相信读者已经了解多次调用 Promise.race() 的问题及其解决方案,可以在自己的项目中应用它们。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6705fc82d91dce0dc8566d9a