相关文章

  1. Promises/A+ 规范(译文)
  2. 用 TS 实现 Promise(官方测试工具测试通过)
  3. 本文代码地址

api 实现

resolve 方法

resolve 方法会返回一个以给定值解析后的 Promise 对象。
resolve 方法的参数 value 可能有三种类型:

  1. value 是一个 Promise;
  2. value 是一个 thenable;
  3. value 既不是 Promise 也不是 thenable。

    function resolve<T>(value: T | PromiseLike<T>): MyPromise<T> {
     // 如果 value 是一个 MyPromise 实例,那么直接返回 value。
     if (value instanceof MyPromise) return value;
     if (
         (typeof value === "object" || typeof value === "function") &&
         "then" in value &&
         typeof value.then === "function"
     ) {
         // 如果 value 是一个 thenable,将它转换成 MyPromise 对象;
         return new MyPromise<T>((_resolve, _reject) => value.then(_resolve, _reject));
     }
     //    如果 value 不是上述两种情况,返回一个用 value 解决的 Promise。
     return new MyPromise<T>((_resolve: Resolve<T>) => {
         _resolve(value);
     });
    }

reject 方法

reject 方法返回一个带有拒绝原因的 Promise 对象。

function reject(reason: any) {
    return new MyPromise((_, _reject: Reject) => {
        _reject(reason);
    });
}

all 方法

all 方法接收一个 Promise 的 iterable 类型(Array, Set, Map...)作为参数,并且只返回一个 Promise 实例。
关于这个返回的 Promise,当它成功时:

  1. 它的 resolve 回调会等待参数中所有 Promise 实例的 resolve 回调执行之后执行;
  2. 它的 value 是一个数组,数组的内容由参数中所有 Promise 实例的 value 组成。

当它失败时:

  1. 它的 reject 回调的执行条件是,参数中任一 Promise 实例的 reject 回调执行;
  2. 它的 reject 回调的 reason 是参数 Promise 中 最先被 reject 抛出的错误信息。
// 根据可迭代协议,实现了 Symbol.iterator 方法的都是可迭代对象。
interface Iterable<T> {
    [Symbol.iterator](): Iterator<T>;
}


function all<T>(promises: Iterable<T | PromiseLike<T>>): MyPromise<any[]> {
    let results = [] as T[]; // 作为返回值的 Promise 的 value
    let promiseCnt = 0;
    let promiseLen = "length" in promises ? Reflect.get(promises, "length") : Reflect.get(promises, "size");
    return new MyPromise((_resolve: Resolve<T[]>, _reject: Reject) => {
        for (let p of promises) {
            // 可迭代对象中的未必一定是 PromiseLike,因此 Promise.resolve 方法进行处理
            resolve(p).then(
                (val) => {
                    results.push(val as T);
                    ++promiseCnt;
                    if (promiseCnt === promiseLen) _resolve(results);
                },
                (err) => {
                    _reject(err);
                }
            );
        }
    });
}

race 方法

race 方法返回一个 Promise,一旦迭代器中的某个 Promise 解决或拒绝,返回的 Promise 就会解决或拒绝。

function race<T>(promises: Iterable<T | PromiseLike<T>>): MyPromise<any> {
    return new MyPromise((_resolve: Resolve<T>, _reject: Reject) => {
        for (let p of promises) {
            resolve(p).then(_resolve, _reject);
        }
    });
}

参考文档

  1. ECMAScript® 2023 Language Specification

知白守黑
1 声望0 粉丝