引言
Promise作为现代JavaScript异步编程的核心,理解其实现原理能帮助开发者更好地处理复杂异步逻辑。本文将带您从零实现一个符合Promise/A+规范的Promise,深入剖析其核心机制。
一、Promise核心架构
1. 基础结构设计
class MyPromise {
constructor(executor) {
this.state = 'pending'; // 状态机:pending/fulfilled/rejected
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);
}
}
}
关键机制:
- 三态管理:pending/fulfilled/rejected状态单向转换
- 回调队列:异步事件管理核心结构
- 立即执行:executor同步执行特性
二、实现链式调用
1. Then方法实现
then(onFulfilled, onRejected) {
const newPromise = new MyPromise((resolve, reject) => {
const handleCallback = (fn, value) => {
setTimeout(() => {
try {
const result = fn ? fn(value) : value;
resolvePromise(newPromise, result, resolve, reject);
} catch (err) {
reject(err);
}
});
};
if (this.state === 'fulfilled') {
handleCallback(onFulfilled, this.value);
} else if (this.state === 'rejected') {
handleCallback(onRejected, this.reason);
} else {
this.onFulfilledCallbacks.push(() => handleCallback(onFulfilled, this.value));
this.onRejectedCallbacks.push(() => handleCallback(onRejected, this.reason));
}
});
return newPromise;
}
2. 值穿透处理
const resolvePromise = (promise, x, resolve, reject) => {
if (promise === x) {
return reject(new TypeError('Chaining cycle detected'));
}
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else if (typeof x === 'object' || typeof x === 'function') {
// 处理thenable对象
let then;
try {
then = x.then;
} catch (err) {
return reject(err);
}
if (typeof then === 'function') {
let called = false;
try {
then.call(x,
y => {
if (!called) {
called = true;
resolvePromise(promise, y, resolve, reject);
}
},
r => {
if (!called) {
called = true;
reject(r);
}
}
);
} catch (err) {
if (!called) reject(err);
}
} else {
resolve(x);
}
} else {
resolve(x);
}
};
核心要点:
- 返回新Promise实现链式调用
- 异步执行保证执行顺序
- 值穿透的递归处理
- 循环引用检测
三、进阶功能实现
1. 静态方法实现
static resolve(value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(value));
}
static reject(reason) {
return new MyPromise((_, reject) => reject(reason));
}
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = [];
let count = 0;
promises.forEach((p, i) => {
MyPromise.resolve(p).then(
res => {
results[i] = res;
if (++count === promises.length) resolve(results);
},
reject
);
});
});
}
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(p => {
MyPromise.resolve(p).then(resolve, reject);
});
});
}
2. 错误边界处理
catch(onRejected) {
return this.then(null, onRejected);
}
finally(callback) {
return this.then(
value => MyPromise.resolve(callback()).then(() => value),
reason => MyPromise.resolve(callback()).then(() => { throw reason })
);
}
四、实现效果验证
// 测试用例
const p = new MyPromise((resolve) => {
setTimeout(() => resolve(100), 1000);
})
.then(res => {
console.log(res); // 100
return res + 100;
})
.then(res => {
console.log(res); // 200
return MyPromise.reject('error');
})
.catch(err => {
console.log(err); // error
});
// 执行结果:
// 100 -> 200 -> error
总结
通过实现:
- 深入理解微任务队列机制
- 掌握Promise链式调用原理
- 熟悉异步编程错误处理模式
- 了解Promise/A+规范实现细节
完整实现代码已上传GitHub(此处添加仓库链接),建议结合测试用例调试理解。掌握核心原理后,可进一步研究async/await的实现机制。
如果本文对你有帮助,欢迎点赞、收藏、关注!你的支持是我创作的最大动力!
诸君共勉!!!