Promise简易polyfill核心是实现构造函数、then链式返回新Promise、pending/fulfilled/rejected状态不可逆管理、微任务调度(queueMicrotask)及resolvePromise值穿透逻辑。

Promise 的简易 polyfill 实现,核心是模拟 Promise 构造函数、then 方法、状态管理(pending/fulfilled/rejected)以及异步调度逻辑。它不追求完全符合规范(如 Promise A+ 测试套件),但能支持基本链式调用、值穿透、错误冒泡和微任务执行语义。
基础结构与状态管理
Promise 本质是一个有状态的对象:初始为 pending,之后只能变为 fulfilled 或 rejected,且不可逆。polyfill 需手动维护状态、成功值(value)和失败原因(reason),并存储待执行的回调队列。
- 构造函数接收一个执行器函数
executor,立即同步调用,并传入resolve和reject两个函数 -
resolve和reject需检查当前是否仍为pending状态,避免多次触发 - 使用数组
onFulfilledCallbacks和onRejectedCallbacks缓存then注册的回调,等状态改变时统一触发
实现 then 方法与链式返回新 Promise
then 必须返回一个新的 Promise,以支持链式调用。其行为分三种情况:正常返回值、返回 Promise、抛出异常。polyfill 中需用 resolvePromise 辅助函数统一处理返回值(即“Promise 解析过程”)。
- 若
onFulfilled或onRejected返回一个值x,则用resolvePromise(promise2, x, resolve, reject)判断是否为 Promise 并透传结果 - 若执行回调时抛错,直接
reject新 Promise - 当当前 Promise 还在
pending状态时,把回调推入对应队列;否则立即异步执行(用queueMicrotask或降级为setTimeout)
微任务调度与兼容性处理
Promise 的 then 回调必须在当前任务结束后、下一个宏任务前执行(即微任务)。polyfill 应优先使用 queueMicrotask,没有则用 Promise.resolve().then(自身 polyfill 下可用降级方案,如 setTimeout(fn, 0),但注意这不是严格微任务)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 推荐封装一个
nextTick工具函数,统一调度回调执行时机 - 避免在
then内部直接同步调用回调——这会破坏异步顺序,导致竞态问题 - 对
resolve传入自身 Promise 的情况(循环引用),需检测并抛出TypeError
简化可运行示例(含关键注释)
以下是最小可行 polyfill,仅包含构造函数、then、resolve、reject 和基础 catch:
function MyPromise(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : r => { throw r; };
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
queueMicrotask(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
} else if (this.state === 'rejected') {
queueMicrotask(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
} else {
this.onFulfilledCallbacks.push(() => {
queueMicrotask(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
this.onRejectedCallbacks.push(() => {
queueMicrotask(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
});
return promise2;
};
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
let called = false;
try {
const then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
}, r => {
if (called) return;
called = true;
reject(r);
});
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}
MyPromise.resolve = function(value) {
return new MyPromise(resolve => resolve(value));
};
MyPromise.reject = function(reason) {
return new MyPromise((_, reject) => reject(reason));
};
MyPromise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};
这个 polyfill 支持基本用法,如 new MyPromise(...).then(...).catch(...) 和 MyPromise.resolve(42).then(console.log)。实际项目中建议使用成熟方案(如 es6-promise),但手写有助于深入理解 Promise 原理。

















