在前一篇文章中,我们实现了符合Promise A+规范的Promise核心功能。本文将聚焦于两个重要的静态方法:Promise.resolve
和 Promise.reject
,带你深入理解它们的实现细节和边界情况处理。
实现Promise.resolve
在MDN规范中,Promise.resolve
有四种情况需要处理:
- Promise实例:如果参数是一个Promise对象,直接返回该对象
- Thenable对象:参数是具有then方法的对象,将其转换为符合规范的Promise
- 普通值:参数是普通值,创建已完成的Promise并返回该值
- 嵌套Thenable:参数是嵌套的thenable对象,需要深度展平返回单个Promise
在之前代码基础上搭建代码基本结构:
js
(function () {
"use strict";
/* 上面代码省略 */
var prototype = Promise.prototype;
function definePropertyConfig(object, key, value) {
Object.defineProperty(object, key, {
value: value,
writable: true,
enumerable: false,
configurable: true,
});
}
// Promise解析核心算法(复用之前实现)
var resolvePromise = function (promise, x, resolve, reject) {
// ... 原有实现,用于处理thenable对象和循环引用
};
function checkPromiseInstance(value) {
if (!(value instanceof Promise)) {
throw new TypeError(
"Method Promise.prototype.then called on incompatible receiver #<Promise>"
);
}
}
definePropertyConfig(Promise, 'resolve', function (value) {
/* 在此处实现resolve */
})
definePropertyConfig(Promise, 'reject', function (value) {
/* 在此处实现reject */
})
/* 下面代码省略 */
})();
参数是Promise对象
js
const p1 = new Promise((resolve) => {
resolve(1);
});
const p2 = Promise.resolve(p1);
console.log(p1 === p2); // true
实现代码:
js
definePropertyConfig(Promise, 'resolve', function (value) {
if (value instanceof Promise) {
return value
}
});
复用resolvePromise处理其他情况
其他三个情况其实就是对具有then方法的深度解析。在上篇文章中已经编写了Promise的解析代码。在此可以复用。
js
definePropertyConfig(Promise, "resolve", function (value) {
if (value instanceof Promise) return value;
return new Promise(function (resolve, reject) {
const p = new Promise(function () {});
resolvePromise(p, value, resolve, reject);
});
});
边界情况处理
js
// 原生Promise代码
var p = Promise.resolve;
p(2) // 此处将会报错
添加防护代码:
js
// Promise.resolve方法最顶部添加以下代码:
if (!(this === Promise)) {
throw new TypeError("PromiseResolve called on non-object");
}
完整的Promise.resolve代码
js
definePropertyConfig(Promise, "resolve", function (value) {
if (!(this === Promise)) {
throw new TypeError("PromiseResolve called on non-object");
}
if (value instanceof Promise) return value;
return new Promise(function (resolve, reject) {
// 为了满足resolvePromise函数的参数要求,循环引用检测
const p = new Promise(function () {});
resolvePromise(p, value, resolve, reject);
});
});
实现Promise.reject
Promise.reject
的实现相对简单,它总是返回一个已拒绝的Promise:
js
definePropertyConfig(Promise, "reject", function (reason) {
// 与Promise.resolve一样
if (!(this === Promise)) {
throw new TypeError("PromiseReject called on non-object");
}
return new Promise(function (_, reject) {
reject(reason);
});
});
小结
通过手写实现Promise.resolve
和Promise.reject
,我们深入理解了:
- 规范一致性:如何确保自定义实现与原生Promise行为完全一致
- 递归解析 :通过
resolvePromise
算法处理复杂的thenable嵌套结构 - 防御性编程:通过上下文检查预防常见的错误用法模式
- 代码复用:充分利用现有逻辑,避免重复实现复杂算法
这些静态方法不仅是工具函数,更是理解Promise生态系统的关键。它们的实现展示了如何将各种类型的值统一封装为标准的Promise对象,为异步编程提供了坚实的基础。
掌握这些实现原理,不仅有助于深入理解Promise工作机制,也为实现其他复杂的异步模式打下了坚实基础。希望对你有一定帮助。ヾ( ̄▽ ̄)ByeBye