HOW - 实现 Promise.race()

一、介绍

MDN Web docs 官方介绍:Promise.race()

The Promise.race() static method takes an iterable of promises as input and returns a single Promise. This returned promise settles with the eventual state of the first promise that settles.

示例:

const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));
Promise.any([promise1, promise2, promise3]).then((value) => console.log(value));
// Expected output: "quick"

二、注意事项

手动实现一个 Promise.race() 需要注意以下几点:

  1. 参数验证:需要确保传入的参数是一个可迭代的对象,例如数组或类数组对象。

  2. 处理空数组情况:如果传入的数组为空,则返回一个永远不会解决的 Promise 对象,因为没有任何 Promise 可以竞速。

  3. 处理非 Promise 对象:需要确保传入的数组中的每个元素都是 Promise 对象,如果有任何一个元素不是 Promise 对象,则需要将其包装为 Promise 对象。

  4. 等待第一个 Promise 解决或拒绝:需要等待传入的所有 Promise 对象中的第一个解决或拒绝。为此,可以使用一个循环来遍历传入的 Promise 数组,并在第一个 Promise 解决或拒绝后解决返回的 Promise 对象。

  5. 处理拒绝情况:如果传入的第一个 Promise 对象拒绝(即状态变为 rejected),则返回的 Promise 对象也应该立即拒绝,并且使用第一个拒绝的 Promise 的拒绝原因作为自己的拒绝原因。

  6. 处理多次调用:一旦有一个 Promise 对象解决或拒绝,返回的 Promise 对象应该立即解决或拒绝,并且忽略后续的 Promise 对象。

  7. 错误处理:需要捕获可能发生的错误,并将其作为拒绝原因传递给返回的 Promise 对象。

综上所述,手动实现一个 Promise.race() 需要考虑参数验证、空数组情况、Promise 对象的包装、等待第一个 Promise 解决或拒绝、处理拒绝情况、处理多次调用以及错误处理等方面的问题。

三、实现

function isPromise(obj) {
	return !!obj && 
		(typeof obj === 'function' || typeof obj === 'object') &&
		typeof obj.then === 'function'
}
function myPromiseRace(promises) {
    // 参数验证
    if (!Array.isArray(promises)) {
        return Promise.reject(new TypeError('参数必须是一个可迭代的对象'));
    }
    // 处理空数组情况
    if (promises.length === 0) {
        return Promise.resolve();
    }
    // 返回一个新的 Promise 对象
    return new Promise((resolve, reject) => {
        // 遍历传入的 Promise 数组
        for (const promise of promises) {
            // 处理非 Promise 对象
            //if (!(promise instanceof Promise)) {
            if (!isPromise(promise)) {
                promise = Promise.resolve(promise);
            }
            // 等待第一个 Promise 解决或拒绝
            promise.then(resolve).catch(reject);
        }
    });
}

// 测试
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => resolve('Promise 1 resolved'), 1000);
});
const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error('Promise 2 rejected')), 500);
});
myPromiseRace([promise1, promise2])
    .then((value) => console.log('Race winner:', value))
    .catch((error) => console.error('Race error:', error));

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
checking whether the compiler supports GNU C++... yes checking whether g++ accepts -g... yes checking for g++ option to enable C++11 features... none needed checking dependency style of g++... gcc3 checking how to run the C preprocessor... gcc -std=gnu11 -E checking for x86_64-w64-mingw32-ranlib... no checking for ranlib... ranlib checking for x86_64-w64-mingw32-dlltool... no checking for dlltool... no checking for x86_64-w64-mingw32-ar... no checking for x86_64-w64-mingw32-lib... no checking for x86_64-w64-mingw32-link... no checking for ar... ar checking the archiver (ar) interface... ar checking dependency style of gcc -std=gnu11... gcc3 checking for x86_64-w64-mingw32-as... no checking for as... as checking whether dlltool supports --temp-prefix... yes checking whether to build a w32api package for Cygwin... no checking whether to build the Win32 libraries... yes checking whether to build the Win64 libraries... yes checking whether to build the WinARM32 libraries... no checking whether to build the WinARM64 libraries... no checking whether to use genlib... no checking whether to enable globbing... no checking whether to enable private exports... no checking whether to enable delay import libs... no checking what to provide as libmsvcrt.a... msvcrt-os checking whether to include support for Control Flow Guard... no checking whether to enable experimental features... no checking whether the compiler supports -municode... no checking for stdio.h... yes checking for stdlib.h... yes checking for string.h... yes checking for inttypes.h... yes checking for stdint.h... yes checking for strings.h... yes checking for sys/stat.h... yes checking for sys/types.h... yes checking for unistd.h... yes checking for _mingw_mac.h... no
最新发布
06-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值