实现 Promise.race
手写 Promise.race 方法
问题
从零实现 Promise.race 方法,返回第一个完成(fulfilled 或 rejected)的 Promise 结果。
解答
Promise.myRace = function(promises) {
return new Promise((resolve, reject) => {
// 将参数转为数组(支持可迭代对象)
const arr = Array.from(promises);
// 空数组时,返回的 Promise 永远 pending
if (arr.length === 0) return;
// 遍历所有 Promise
for (const p of arr) {
// 用 Promise.resolve 包装,处理非 Promise 值
Promise.resolve(p).then(resolve, reject);
}
});
};
测试用例
// 测试1:正常竞速
const p1 = new Promise(resolve => setTimeout(() => resolve('p1'), 100));
const p2 = new Promise(resolve => setTimeout(() => resolve('p2'), 50));
const p3 = new Promise(resolve => setTimeout(() => resolve('p3'), 200));
Promise.myRace([p1, p2, p3]).then(console.log); // 'p2'
// 测试2:包含非 Promise 值
Promise.myRace([p1, 'immediate', p3]).then(console.log); // 'immediate'
// 测试3:第一个 reject
const p4 = new Promise((_, reject) => setTimeout(() => reject('error'), 30));
Promise.myRace([p1, p4, p3])
.then(console.log)
.catch(console.error); // 'error'
关键点
- 返回新 Promise,第一个 settled 的结果决定最终状态
- 用
Promise.resolve()包装每个元素,兼容非 Promise 值 - 多次调用
resolve/reject只有第一次生效,无需额外判断 - 空数组返回永远 pending 的 Promise(与原生行为一致)
- 不需要索引,谁先完成谁说了算
目录