手写Promise--教学版本

手写 Promise 实现与原理(面试向)

目标:

  • 理解 Promise 的状态机模型
  • 掌握 then 链式调用的本质
  • 能在面试中手写 + 讲清楚 Promise 核心机制

一、Promise 的核心概念

Promise 本质是一个 状态机,只存在三种状态:

  • pending(进行中)
  • fulfilled(已成功)
  • rejected(已失败)

状态特性

  1. 状态一旦改变,不可逆

  2. pending → fulfilledpending → rejected

  3. 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 的三大职责

  1. 处理 fulfilled / rejected 状态
  2. 支持 then 链式调用
  3. 支持异常向后传递

四、then 的默认行为(非常重要)

javascript 复制代码
if (typeof onResolve !== 'function') {
  onResolve = value => value
}

if (typeof onReject !== 'function') {
  onReject = reason => { throw reason }
}

为什么要这样?

  • 保证 值穿透

    javascript 复制代码
    Promise.resolve(1).then().then(v => console.log(v)) // 1
  • 保证 错误冒泡

    javascript 复制代码
    Promise.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 原理复盘
  • 手写代码能力展示
相关推荐
努力早日退休2 小时前
Antd Image标签父元素会比图片本身高几个像素的原因
前端
ETA82 小时前
`console.log([1,2,3].map(parseInt))` 深入理解 JavaScript 中的高阶函数与类型机制
前端·javascript
呼叫69452 小时前
图片列表滚动掉帧的原因分析与解决方案
前端
狗哥哥2 小时前
AI 驱动前端自动化测试:一套能落地、能协作、能持续的工程化方案
前端·测试
全栈老石2 小时前
别再折腾端口转发了:使用 Cloudflare Tunnel 优雅地分享你的 localhost
前端·后端·全栈
码云之上2 小时前
WEB端小屏切换纯CSS实现
前端·css
Java编程爱好者2 小时前
JUnit 5 中的 @ClassTemplate 实战指南
javascript
LaughingDangZi2 小时前
vue+java分离项目实现微信公众号开发全流程梳理
java·前端·后端