手写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 原理复盘
  • 手写代码能力展示
相关推荐
Moment3 分钟前
富文本编辑器技术选型,到底是 Prosemirror 还是 Tiptap 好 ❓❓❓
前端·javascript·面试
xkxnq7 分钟前
第二阶段:Vue 组件化开发(第 18天)
前端·javascript·vue.js
晓得迷路了9 分钟前
栗子前端技术周刊第 112 期 - Rspack 1.7、2025 JS 新星榜单、HTML 状态调查...
前端·javascript·html
怕浪猫11 分钟前
React从入门到出门 第五章 React Router 配置与原理初探
前端·javascript·react.js
jinmo_C++12 分钟前
从零开始学前端 · HTML 基础篇(一):认识 HTML 与页面结构
前端·html·状态模式
鹏多多18 分钟前
前端2025年终总结:借着AI做大做强再创辉煌
前端·javascript
哈__21 分钟前
React Native 鸿蒙跨平台开发:Vibration 实现鸿蒙端设备的震动反馈
javascript·react native·react.js
WebGISer_白茶乌龙桃23 分钟前
Cesium实现“悬浮岛”式,三维立体的行政区划
javascript·vue.js·3d·web3·html5·webgl
小Tomkk26 分钟前
⭐️ StarRocks Web 使用介绍与实战指南
前端·ffmpeg
不一样的少年_30 分钟前
产品催: 1 天优化 Vue 官网 SEO?我用这个插件半天搞定(不重构 Nuxt)
前端·javascript·vue.js