相干文章
- Promises/A+ 标准(译文)
- 用 TS 实现 Promise(官网测试工具测试通过)
- 本文代码地址
api 实现
resolve 办法
resolve 办法会返回一个以给定值解析后的 Promise 对象。
resolve 办法的参数 value 可能有三种类型:
- value 是一个 Promise;
- value 是一个 thenable;
-
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 对象;* 如果 value 是一个嵌套的 thenable,那么它会被展平。**/ value.then((val: T | PromiseLike<T>) => resolve(val)); } // 如果 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,当它胜利时:
- 它的 resolve 回调会期待参数中所有 Promise 实例的 resolve 回调执行之后执行;
- 它的 value 是一个数组,数组的内容由参数中所有 Promise 实例的 value 组成。
当它失败时:
- 它的 reject 回调的执行条件是,参数中任一 Promise 实例的 reject 回调执行;
- 它的 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);
}
});
}
参考文档
- ECMAScript® 2023 Language Specification