在 ECMAScript 2016 (ES7) 中,Promise.race 方法被添加到了 Promise API 中。它可以用来同时观察多个 Promise 对象,并返回一个新的 Promise,该 Promise 将在其中任何一个 Promise 成功或失败时解决。
Promise.race 方法的语法
Promise.race 方法的语法如下:
Promise.race(iterable);
其中,iterable
是一个可迭代对象,其中包含多个 Promise 对象。
Promise.race 方法的应用
Promise.race 方法可以用于以下场景:
1. 多个异步操作中只需要一个完成
在某些情况下,我们可能需要同时观察多个异步操作,并在其中任何一个操作完成时进行处理。
例如,我们需要从多个不同的 API 中获取数据,但我们只需要其中一个 API 的数据即可。我们可以使用 Promise.race 方法来观察这些异步操作,并在其中任何一个操作完成时获取数据。
const api1 = fetch('/api1'); const api2 = fetch('/api2'); const api3 = fetch('/api3'); Promise.race([api1, api2, api3]).then(response => { console.log('Data from', response.url); });
在上面的代码中,我们使用 Promise.race 方法同时观察了三个异步操作,即从 /api1
、/api2
和 /api3
获取数据的操作。当其中任何一个操作完成时,我们会通过 then
方法获取其响应数据,并在控制台输出响应的 URL。
2. 多个异步操作中只需要一个成功
在某些情况下,我们可能需要同时观察多个异步操作,并在其中任何一个操作成功时进行处理。
例如,我们需要从多个不同的 API 中获取数据,但我们只需要其中一个 API 的数据,并且我们只关心获取数据的成功与否。我们可以使用 Promise.race 方法来观察这些异步操作,并在其中任何一个操作成功时处理成功情况。
const api1 = fetch('/api1'); const api2 = fetch('/api2'); const api3 = fetch('/api3'); Promise.race([api1, api2, api3].map(p => p.catch(() => undefined))).then(response => { console.log('Data from', response.url); });
在上面的代码中,我们使用 Promise.race 方法同时观察了三个异步操作,即从 /api1
、/api2
和 /api3
获取数据的操作。当其中任何一个操作成功时,我们会通过 then
方法获取其响应数据,并在控制台输出响应的 URL。
注意,我们在 map
方法中使用了 catch
方法来捕获每个 Promise 对象的失败情况。这是因为在使用 Promise.race 方法时,如果其中一个 Promise 对象失败了,整个 Promise.race 方法也会失败,从而导致 then
方法无法执行。因此,我们需要通过 catch
方法将失败情况转化为 undefined,以使 Promise.race 方法可以正常执行。
Promise.race 方法的注意事项
在使用 Promise.race 方法时,需要注意以下事项:
1. 某些 Promise 可能永远不会解决
当同时观察多个 Promise 对象时,如果其中一个 Promise 对象永远不会解决,那么 Promise.race 方法也永远不会解决。
例如,我们在以下代码中同时观察了一个永远不会解决的 Promise 对象和一个可以解决的 Promise 对象:
const neverResolvedPromise = new Promise(() => {}); const resolvedPromise = Promise.resolve('Data from API'); Promise.race([neverResolvedPromise, resolvedPromise]).then(response => { console.log('Data from', response); });
在上面的代码中,我们创建了一个永远不会解决的 Promise 对象 neverResolvedPromise
和一个可以解决的 Promise 对象 resolvedPromise
,并将它们传递给 Promise.race 方法。由于 neverResolvedPromise
永远不会解决,因此 Promise.race 方法也永远不会解决,从而导致 then
方法无法执行。
2. 可迭代对象必须至少包含一个 Promise 对象
在使用 Promise.race 方法时,传递给它的可迭代对象必须至少包含一个 Promise 对象,否则会抛出 TypeError 异常。
例如,我们在以下代码中传递了一个空数组给 Promise.race 方法:
Promise.race([]).then(response => { console.log('Data from', response.url); });
在上面的代码中,我们传递了一个空数组给 Promise.race 方法,由于该数组中不包含任何 Promise 对象,因此会抛出 TypeError 异常。
结论
Promise.race 方法是一个非常有用的 Promise API,它可以同时观察多个异步操作,并在其中任何一个操作完成时进行处理。在使用 Promise.race 方法时,需要注意某些 Promise 可能永远不会解决,以及可迭代对象必须至少包含一个 Promise 对象的问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6765b7ee76af2b9a20efaa6b