Search K
Appearance
Appearance
📊 SEO元描述:2024年最新JavaScript手写Promise实现教程,从零构建完整Promise源码,详解Promise/A+规范、状态管理、链式调用实现。包含完整代码和测试用例,适合高级前端开发者深入理解Promise原理。
核心关键词:JavaScript手写Promise 2024、Promise源码实现、Promise/A+规范、手写Promise面试、JavaScript异步原理
长尾关键词:如何手写Promise、Promise源码解析、Promise/A+规范实现、手写Promise完整版、JavaScript Promise原理详解
通过本节JavaScript手写Promise实现详解,你将系统性掌握:
Promise/A+规范是什么?这是理解Promise实现的基础标准。Promise/A+规范定义了Promise的状态管理、then方法行为、值传递机制等核心特性,是所有Promise实现必须遵循的标准。
💡 学习建议:理解Promise/A+规范是手写Promise的基础,建议先熟悉规范要求,再逐步实现每个特性。
// 🎉 基础Promise实现
console.log("=== 基础Promise实现 ===");
// Promise的三种状态常量
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
// 初始状态为pending
this.state = PENDING;
this.value = undefined;
this.reason = undefined;
// 存储then方法的回调函数
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
// resolve函数
const resolve = (value) => {
// 只有pending状态才能转换
if (this.state === PENDING) {
this.state = FULFILLED;
this.value = value;
// 执行所有成功回调
this.onFulfilledCallbacks.forEach(callback => {
callback(value);
});
}
};
// reject函数
const reject = (reason) => {
// 只有pending状态才能转换
if (this.state === PENDING) {
this.state = REJECTED;
this.reason = reason;
// 执行所有失败回调
this.onRejectedCallbacks.forEach(callback => {
callback(reason);
});
}
};
// 执行executor,捕获同步错误
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
// then方法的基础实现
then(onFulfilled, onRejected) {
// 参数可选,提供默认值
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };
// 返回新的Promise实现链式调用
return new MyPromise((resolve, reject) => {
// 处理fulfilled状态
const handleFulfilled = () => {
// 异步执行回调(微任务)
setTimeout(() => {
try {
const result = onFulfilled(this.value);
resolve(result);
} catch (error) {
reject(error);
}
}, 0);
};
// 处理rejected状态
const handleRejected = () => {
// 异步执行回调(微任务)
setTimeout(() => {
try {
const result = onRejected(this.reason);
resolve(result);
} catch (error) {
reject(error);
}
}, 0);
};
// 根据当前状态执行相应逻辑
if (this.state === FULFILLED) {
handleFulfilled();
} else if (this.state === REJECTED) {
handleRejected();
} else if (this.state === PENDING) {
// 如果还是pending状态,将回调存储起来
this.onFulfilledCallbacks.push(handleFulfilled);
this.onRejectedCallbacks.push(handleRejected);
}
});
}
// catch方法
catch(onRejected) {
return this.then(null, onRejected);
}
// finally方法
finally(onFinally) {
return this.then(
value => {
return MyPromise.resolve(onFinally()).then(() => value);
},
reason => {
return MyPromise.resolve(onFinally()).then(() => { throw reason; });
}
);
}
// 静态resolve方法
static resolve(value) {
// 如果是Promise实例,直接返回
if (value instanceof MyPromise) {
return value;
}
return new MyPromise(resolve => {
resolve(value);
});
}
// 静态reject方法
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
}
}
// 测试基础Promise实现
function testBasicPromise() {
console.log("1. 测试基础Promise实现");
// 测试resolve
const promise1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve("成功结果");
}, 1000);
});
promise1
.then(value => {
console.log("✅ Promise resolved:", value);
return "链式调用结果";
})
.then(value => {
console.log("✅ 链式调用:", value);
})
.catch(error => {
console.log("❌ Promise rejected:", error);
});
// 测试reject
const promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject(new Error("失败原因"));
}, 1500);
});
promise2
.then(value => {
console.log("这行不会执行");
})
.catch(error => {
console.log("✅ 错误被捕获:", error.message);
});
// 测试同步错误
const promise3 = new MyPromise((resolve, reject) => {
throw new Error("同步错误");
});
promise3.catch(error => {
console.log("✅ 同步错误被捕获:", error.message);
});
}
testBasicPromise();// 🎉 完善的Promise实现
console.log("=== 完善的Promise实现 ===");
// 判断是否为thenable对象
function isThenable(value) {
return value !== null &&
(typeof value === 'object' || typeof value === 'function') &&
typeof value.then === 'function';
}
// Promise解析过程(Promise Resolution Procedure)
function resolvePromise(promise, x, resolve, reject) {
// 避免循环引用
if (promise === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
// 避免重复调用
let called = false;
// 如果x是Promise实例
if (x instanceof AdvancedPromise) {
if (x.state === PENDING) {
x.then(
value => resolvePromise(promise, value, resolve, reject),
reject
);
} else {
x.then(resolve, reject);
}
return;
}
// 如果x是thenable对象
if (isThenable(x)) {
try {
const then = x.then;
then.call(
x,
value => {
if (called) return;
called = true;
resolvePromise(promise, value, resolve, reject);
},
reason => {
if (called) return;
called = true;
reject(reason);
}
);
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
// 普通值直接resolve
resolve(x);
}
}
class AdvancedPromise {
constructor(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(callback => callback());
}
};
const reject = (reason) => {
if (this.state === PENDING) {
this.state = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(callback => callback());
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };
const promise2 = new AdvancedPromise((resolve, reject) => {
const handleFulfilled = () => {
// 使用微任务模拟
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
};
const handleRejected = () => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
};
if (this.state === FULFILLED) {
handleFulfilled();
} else if (this.state === REJECTED) {
handleRejected();
} else {
this.onFulfilledCallbacks.push(handleFulfilled);
this.onRejectedCallbacks.push(handleRejected);
}
});
return promise2;
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(onFinally) {
return this.then(
value => AdvancedPromise.resolve(onFinally()).then(() => value),
reason => AdvancedPromise.resolve(onFinally()).then(() => { throw reason; })
);
}
// 静态方法实现
static resolve(value) {
if (value instanceof AdvancedPromise) {
return value;
}
return new AdvancedPromise(resolve => {
resolve(value);
});
}
static reject(reason) {
return new AdvancedPromise((resolve, reject) => {
reject(reason);
});
}
static all(promises) {
return new AdvancedPromise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('参数必须是数组'));
}
if (promises.length === 0) {
return resolve([]);
}
const results = [];
let completedCount = 0;
promises.forEach((promise, index) => {
AdvancedPromise.resolve(promise)
.then(value => {
results[index] = value;
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
})
.catch(reject);
});
});
}
static race(promises) {
return new AdvancedPromise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('参数必须是数组'));
}
promises.forEach(promise => {
AdvancedPromise.resolve(promise)
.then(resolve)
.catch(reject);
});
});
}
static allSettled(promises) {
return new AdvancedPromise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('参数必须是数组'));
}
if (promises.length === 0) {
return resolve([]);
}
const results = [];
let completedCount = 0;
promises.forEach((promise, index) => {
AdvancedPromise.resolve(promise)
.then(value => {
results[index] = { status: 'fulfilled', value };
})
.catch(reason => {
results[index] = { status: 'rejected', reason };
})
.finally(() => {
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
});
});
});
}
static any(promises) {
return new AdvancedPromise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('参数必须是数组'));
}
if (promises.length === 0) {
return reject(new AggregateError([], 'All promises were rejected'));
}
const errors = [];
let rejectedCount = 0;
promises.forEach((promise, index) => {
AdvancedPromise.resolve(promise)
.then(resolve) // 任何一个成功就resolve
.catch(reason => {
errors[index] = reason;
rejectedCount++;
if (rejectedCount === promises.length) {
reject(new AggregateError(errors, 'All promises were rejected'));
}
});
});
});
}
}
// 测试完善的Promise实现
function testAdvancedPromise() {
console.log("2. 测试完善的Promise实现");
// 测试Promise解析
const promise1 = new AdvancedPromise(resolve => {
resolve(new AdvancedPromise(resolve => {
setTimeout(() => resolve("嵌套Promise结果"), 1000);
}));
});
promise1.then(value => {
console.log("✅ 嵌套Promise解析:", value);
});
// 测试thenable对象
const thenable = {
then(resolve, reject) {
setTimeout(() => resolve("thenable结果"), 1500);
}
};
AdvancedPromise.resolve(thenable).then(value => {
console.log("✅ thenable对象解析:", value);
});
// 测试静态方法
const promises = [
AdvancedPromise.resolve("结果1"),
new AdvancedPromise(resolve => setTimeout(() => resolve("结果2"), 800)),
AdvancedPromise.resolve("结果3")
];
AdvancedPromise.all(promises).then(results => {
console.log("✅ Promise.all结果:", results);
});
AdvancedPromise.race(promises).then(result => {
console.log("✅ Promise.race结果:", result);
});
}
testAdvancedPromise();// 🎉 Promise性能测试和验证
console.log("=== Promise性能测试和验证 ===");
// Promise规范测试套件
class PromiseTestSuite {
constructor(PromiseImplementation) {
this.Promise = PromiseImplementation;
this.testResults = [];
}
// 运行所有测试
async runAllTests() {
console.log("开始Promise规范测试...");
await this.testBasicFunctionality();
await this.testChaining();
await this.testErrorHandling();
await this.testStaticMethods();
await this.testEdgeCases();
this.printResults();
}
// 基础功能测试
async testBasicFunctionality() {
console.log("1. 基础功能测试");
// 测试resolve
try {
const result = await new this.Promise(resolve => resolve("test"));
this.assert(result === "test", "基础resolve测试");
} catch (error) {
this.assert(false, "基础resolve测试", error.message);
}
// 测试reject
try {
await new this.Promise((resolve, reject) => reject(new Error("test error")));
this.assert(false, "基础reject测试");
} catch (error) {
this.assert(error.message === "test error", "基础reject测试");
}
// 测试异步resolve
try {
const result = await new this.Promise(resolve => {
setTimeout(() => resolve("async test"), 100);
});
this.assert(result === "async test", "异步resolve测试");
} catch (error) {
this.assert(false, "异步resolve测试", error.message);
}
}
// 链式调用测试
async testChaining() {
console.log("2. 链式调用测试");
try {
const result = await this.Promise.resolve(1)
.then(x => x + 1)
.then(x => x * 2)
.then(x => `结果: ${x}`);
this.assert(result === "结果: 4", "链式调用测试");
} catch (error) {
this.assert(false, "链式调用测试", error.message);
}
// 测试Promise返回
try {
const result = await this.Promise.resolve(1)
.then(x => new this.Promise(resolve => {
setTimeout(() => resolve(x * 10), 100);
}));
this.assert(result === 10, "Promise返回测试");
} catch (error) {
this.assert(false, "Promise返回测试", error.message);
}
}
// 错误处理测试
async testErrorHandling() {
console.log("3. 错误处理测试");
// 测试catch
try {
const result = await this.Promise.reject(new Error("test"))
.catch(error => "caught: " + error.message);
this.assert(result === "caught: test", "catch测试");
} catch (error) {
this.assert(false, "catch测试", error.message);
}
// 测试错误传播
try {
await this.Promise.resolve(1)
.then(x => { throw new Error("chain error"); })
.then(x => x + 1);
this.assert(false, "错误传播测试");
} catch (error) {
this.assert(error.message === "chain error", "错误传播测试");
}
}
// 静态方法测试
async testStaticMethods() {
console.log("4. 静态方法测试");
// 测试Promise.all
try {
const results = await this.Promise.all([
this.Promise.resolve(1),
this.Promise.resolve(2),
this.Promise.resolve(3)
]);
this.assert(
JSON.stringify(results) === JSON.stringify([1, 2, 3]),
"Promise.all测试"
);
} catch (error) {
this.assert(false, "Promise.all测试", error.message);
}
// 测试Promise.race
try {
const result = await this.Promise.race([
new this.Promise(resolve => setTimeout(() => resolve("slow"), 200)),
this.Promise.resolve("fast")
]);
this.assert(result === "fast", "Promise.race测试");
} catch (error) {
this.assert(false, "Promise.race测试", error.message);
}
}
// 边界情况测试
async testEdgeCases() {
console.log("5. 边界情况测试");
// 测试循环引用
try {
const promise = new this.Promise(resolve => {
resolve(promise);
});
await promise;
this.assert(false, "循环引用测试");
} catch (error) {
this.assert(
error instanceof TypeError && error.message.includes("cycle"),
"循环引用测试"
);
}
// 测试多次resolve
try {
let resolveCount = 0;
const promise = new this.Promise(resolve => {
resolve("first");
resolve("second"); // 应该被忽略
});
promise.then(value => {
resolveCount++;
this.assert(value === "first" && resolveCount === 1, "多次resolve测试");
});
} catch (error) {
this.assert(false, "多次resolve测试", error.message);
}
}
// 断言方法
assert(condition, testName, errorMessage = "") {
const result = {
name: testName,
passed: condition,
error: errorMessage
};
this.testResults.push(result);
if (condition) {
console.log(`✅ ${testName}`);
} else {
console.log(`❌ ${testName}: ${errorMessage}`);
}
}
// 打印测试结果
printResults() {
const passed = this.testResults.filter(r => r.passed).length;
const total = this.testResults.length;
console.log(`\n测试完成: ${passed}/${total} 通过`);
if (passed === total) {
console.log("🎉 所有测试通过!Promise实现符合规范");
} else {
console.log("⚠️ 部分测试失败,需要修复");
}
}
}
// 性能对比测试
function performanceComparison() {
console.log("6. 性能对比测试");
const testCount = 1000;
// 测试原生Promise
console.time("原生Promise");
const nativePromises = Array.from({ length: testCount }, (_, i) => {
return Promise.resolve(i).then(x => x * 2);
});
Promise.all(nativePromises).then(() => {
console.timeEnd("原生Promise");
// 测试自实现Promise
console.time("自实现Promise");
const customPromises = Array.from({ length: testCount }, (_, i) => {
return AdvancedPromise.resolve(i).then(x => x * 2);
});
AdvancedPromise.all(customPromises).then(() => {
console.timeEnd("自实现Promise");
});
});
}
// 运行测试
const testSuite = new PromiseTestSuite(AdvancedPromise);
testSuite.runAllTests();
setTimeout(() => {
performanceComparison();
}, 3000);通过本节JavaScript手写Promise实现详解的学习,你已经掌握:
A: 主要考察对异步编程原理的理解、JavaScript事件循环机制的掌握、面向对象编程能力,以及对Promise/A+规范的深入理解。
A: 自实现Promise的性能通常比原生Promise稍差,因为原生实现经过了高度优化。但理解实现原理对提升编程能力很有价值。
A: Promise解析过程需要处理各种边界情况,如循环引用、thenable对象、嵌套Promise等,这些都是为了保证Promise行为的一致性和可靠性。
A: 可以添加详细的日志输出,使用断点调试,编写完整的测试用例,以及对比原生Promise的行为来发现问题。
A: 虽然实际工作中使用原生Promise,但手写Promise能帮助深入理解异步编程原理,提升解决复杂异步问题的能力,在面试中也是重要考点。
"手写Promise实现是深入理解JavaScript异步编程的最佳方式。通过本节的学习,你已经从底层掌握了Promise的工作原理,这将为你在异步编程领域的进一步发展奠定坚实的基础。继续学习async/await等现代异步编程技术,你将成为JavaScript异步编程的专家!"