手写 Promise 实现与原理(面试向)
目标:
- 理解 Promise 的状态机模型
- 掌握 then 链式调用的本质
- 能在面试中手写 + 讲清楚 Promise 核心机制
一、Promise 的核心概念
Promise 本质是一个 状态机,只存在三种状态:
pending(进行中)fulfilled(已成功)rejected(已失败)
状态特性
-
状态一旦改变,不可逆
-
pending → fulfilled或pending → rejected -
Promise 内部维护:
- 当前状态
PromiseState - 当前结果
PromiseResult - 回调队列
callBacks
- 当前状态
二、Promise 构造函数实现
ini
function Promise(executor) {
this.PromiseState = "pending"
this.PromiseResult = null
this.callBacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== "pending") return
self.PromiseState = "fulfilled"
self.PromiseResult = data
self.callBacks.forEach(cb => cb.onResolve && cb.onResolve(data))
}
function reject(reason) {
if (self.PromiseState !== "pending") return
self.PromiseState = "rejected"
self.PromiseResult = reason
self.callBacks.forEach(cb => cb.onReject && cb.onReject(reason))
}
try {
executor(resolve, reject)
} catch (err) {
reject(err)
}
}
设计要点
- 使用
self = this确保 this 指向稳定 - executor 执行包裹在
try / catch中,异常直接reject - resolve / reject 中做 状态保护,防止多次调用
- 这里你也可以用箭头函数的特性实现,不过用self更好理解
三、then 方法的核心思想
then 的本质:返回一个新的 Promise
then 的三大职责
- 处理 fulfilled / rejected 状态
- 支持 then 链式调用
- 支持异常向后传递
四、then 的默认行为(非常重要)
javascript
if (typeof onResolve !== 'function') {
onResolve = value => value
}
if (typeof onReject !== 'function') {
onReject = reason => { throw reason }
}
为什么要这样?
-
保证 值穿透:
javascriptPromise.resolve(1).then().then(v => console.log(v)) // 1 -
保证 错误冒泡:
javascriptPromise.reject('err').then().then(null, e => console.log(e))
五、then 的完整实现
javascript
Promise.prototype.then = function (onResolve, onReject) {
const self = this
if (typeof onResolve !== "function") onResolve = v => v
if (typeof onReject !== "function") onReject = r => { throw r }
return new Promise((resolve, reject) => {
function handle(callback) {
try {
const result = callback(self.PromiseResult)
if (result instanceof Promise) {
result.then(resolve, reject)
} else {
resolve(result)
}
} catch (err) {
reject(err)
}
}
if (self.PromiseState === "fulfilled") {
handle(onResolve)
}
if (self.PromiseState === "rejected") {
handle(onReject)
}
if (self.PromiseState === "pending") {
self.callBacks.push({
onResolve() { handle(onResolve) },
onReject() { handle(onReject) }
})
}
})
}
六、Promise 链式调用原理
javascript
new Promise(r => r(1))
.then(v => v + 1)
.then(v => new Promise(r => r(v + 1)))
.then(console.log) // 3
原理总结
- then 必须返回新 Promise
- 上一个 then 的返回值,决定下一个 then 的状态
- 返回普通值 → fulfilled
- 返回 Promise → 状态由该 Promise 决定
- 抛异常 → rejected
七、Promise.resolve / Promise.reject 实现
javascript
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
Promise.reject = function (reason) {
return new Promise((_, reject) => reject(reason))
}
八、当前实现的不足(面试加分点)
1️ then 回调是同步的
- 原生 Promise 的 then 回调是 微任务
- 可用
queueMicrotask / setTimeout模拟
2️ 使用了 instanceof Promise
- 规范中使用 thenable 解析
{ then(resolve) { resolve(1) } }也应被视为 Promise
九、面试总结一句话
Promise 的核心是状态机模型,then 返回新 Promise,
通过默认回调实现值穿透和错误冒泡,
真正规范实现中 then 回调会被放入微任务队列执行。
十、阶段总结
已掌握:
- Promise 状态流转
- then 链式调用本质
- 错误捕获与传递
下一步:
- Promise/A+ 规范(resolvePromise)
- 微任务调度实现
本笔记适用于:
- 前端实习 / 校招面试
- Promise 原理复盘
- 手写代码能力展示