推荐答案
-- -------------------- ---- ------- ------------ - -------- ---------- - ------ --- ----------------- ------- -- - -- ---------- -- --------------- --- -- - ---------- -- -- ---------- ------------------ ---- -------- ---- ------------ ------ ------- - --- ------ ------- -- --------- - -------------------------------------- -------- - --- --
本题详细解读
题目要求
手写实现 Promise.race
方法。Promise.race
接收一个 Promise 数组,并返回一个新的 Promise。新 Promise 的状态和值取决于数组中第一个 settled(即 fulfilled 或 rejected)的 Promise。
实现思路
创建并返回新的 Promise:
Promise.race
本身需要返回一个新的 Promise,这是异步操作的基本结构。处理空数组情况: 如果传入的
promises
数组为空,根据 ECMAScript 标准,返回的 Promise 应该立即 resolve 一个undefined
值。(也有实现会直接reject一个AggregateError
,看具体需求)。遍历 Promise 数组: 使用
for...of
循环遍历输入的promises
数组。处理非 Promise 值: 使用
Promise.resolve()
将遍历到的元素转换为 Promise,确保能够使用.then()
。这可以使Promise.race
能够处理非 Promise 的值,如普通值或thenable
对象。绑定 then 处理: 对于每一个转换后的 Promise,使用
.then(resolve, reject)
方法,其中resolve
和reject
直接来自外部创建的Promise
。
- 一旦有任何一个 Promise fulfilled,外层的
Promise
将立即 resolve,并携带该值。 - 一旦有任何一个 Promise rejected,外层的
Promise
将立即 reject,并携带该原因。 - 注意:这里关键在于,第一个 settled 的 Promise 将决定返回 Promise 的状态和值,后续的 settled 的 Promise 将被忽略。
- 返回新 Promise: 返回创建的
Promise
实例。
代码解释
Promise.race = function (promises) { ... }
: 定义Promise.race
函数,并接受 Promise 数组promises
作为参数。return new Promise((resolve, reject) => { ... })
: 创建并返回一个新的 Promise,其状态和值将在内部异步决定。if (!promises || promises.length === 0) { resolve(); return;}
: 处理传入空数组的情况,直接resolve。for (const promise of promises) { ... }
: 循环遍历promises
数组。Promise.resolve(promise).then(resolve, reject);
: 使用Promise.resolve()
将数组项转换为 Promise,然后使用.then()
绑定 resolve 和 reject 处理。- 一旦
then
方法被调用,无论 resolve 或 reject,都会触发外部 Promise 的状态变更,并且由于race
的特性,只会触发一次,后面的都不会生效。
关键点
- 短路行为:
race
的关键在于“短路”行为,即第一个 settled 的 Promise 决定最终结果。 - Promise.resolve():
Promise.resolve()
将非 Promise 值转换为 Promise,确保then()
可以被调用。 - 错误处理: 本实现中,任何一个 Promise reject,外部返回的 Promise 也会 reject。