Promise 有 pending、fulfilled、rejected 三种状态,状态一旦改变不可逆;2. 通过 then 方法注册回调并返回新 Promise 实现链式调用;3. 回调异步执行,使用 queueMicrotask 模拟微任务;4. resolvePromise 函数处理 then 返回值,若为 Promise 则递归解析,否则直接 resolve;5. 需防止循环引用和多次调用,确保错误冒泡。

Promise 是 JavaScript 中处理异步操作的核心机制,理解其底层原理有助于更好地掌握异步编程。下面从手写一个简易但核心功能完整的 Promise 出发,深入剖析其实现逻辑。
一个符合 Promise/A+ 规范的实现必须满足以下几点:
我们基于这些规则来实现一个简化版的 MyPromise。
先定义构造函数和基本状态:
立即学习“Java免费学习笔记(深入)”;
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);
}
}
这里通过数组缓存未执行的回调,确保在异步 resolve/reject 后仍能正确触发。
then 方法是 Promise 的核心,需返回一个新的 Promise 以支持链式调用:
MyPromise.prototype.then = function(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };
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);
}
});
}
if (this.state === 'rejected') {
queueMicrotask(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
}
if (this.state === 'pending') {
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;
};
注意使用 queueMicrotask 模拟微任务执行,保证回调异步且优先于 setTimeout。
Promise 链的关键在于 resolvePromise 函数,它决定如何处理 then 回调的返回值:
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected'));
}
let called;
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
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);
}
}
这段逻辑判断返回值是否为 Promise,如果是则递归解析,否则直接 resolve。
基本上就这些。虽然省略了 catch、finally、all、race 等方法,但核心机制已完整。手写一遍能真正理解 Promise 如何解决回调地狱、实现链式调用和错误冒泡。不复杂但容易忽略细节,比如循环引用、多次调用保护、异步调度等。
以上就是手写Promise核心原理及源码实现_javascript技巧的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号