为了深入理解Promise,我重写的MiniPromise,能成为理解异步编程的终极利器吗?

更新于
2026-10-28 20:06:59
21阅读来源:SEO教程
  • 内容介绍
  • 文章标签
  • 相关问答
不过,

话说回来

至于前言。为什么重写 MiniPromise 才是理解异步编程的终极利器?老实说,

你是不是也曾这样痛苦过?

为了深入理解Promise,我重写的MiniPromise,能成为理解异步编程的终极利器吗?
  • 面试被问手写 Promise,只能机械地复制粘贴代码,但还是搞不懂原理
  • 看 Promise/A+ 规范。看了一遍又一遍却还是云里雾里
  • .n、Promise.all、async/await...这些概念在脑海中永远是支离破碎的知识点

这篇文章不打算直接贴完整代码。而是带你通过最小可行的 MiniPromise,从零理解 Promise 的设计思路。怎么说呢,

1. 先想清楚:Promise 本质上解决什么问题?

在 Promise 出现之前,我们用回调函数处理异步:


fetchData {
// ...回调地狱
})))));

痛点一:回调地狱不仅仅是嵌套难读!

  • 错误处理分散到各个层级,难以统一管理
  • 状态不可控 - 每个回调都可能修改全局状态导致难以维护
  • 业务逻辑被拆分到不同层级。可读性极差

Promise 的主要思路就两点: 1. 状态机模型 2. 链式调用返回新的Promise)

2. MiniPromise 的主要结构揭秘:仅需3个属性就能实现!


class MiniPromise {
constructor {
this.state = 'pending';// 初始状态
this.value = undefined;// 暂存结果
this.onFulfilledCallbacks =;// 满足时回调队列
this.onRejectedCallbacks =;// 拒绝时回调队列
const resolve = value => this._resolve;const reject = reason => this._reject;try {
executor;// 开始执行任务
} catch {
reject;按理说,}
}
}

⚠️ 注意!这里才是所有魔法的关键,⚠️

为什么只有4个主要属性就能实现完整功能?因为本质上 Promise 是一个有限状态机 + 异步任务管理器!

为了深入理解Promise,我重写的MiniPromise,能成为理解异步编程的终极利器吗?

_resolve {
if return;if { // 特殊处理情况
return value.n(
this._resolve.bind,this._reject.bind
);}
setTimeout => { // 必须异步执行!this.state = 'fulfilled';this.value = value;
this.onFulfilledCallbacks.forEach);},0),}

  • 为什么要检查当前状态不是 pending?: Avoid double resolution - 一旦转移了状态就不能再变了;,;,;,;,.>.>.>.>.>.>.>.>.>.
  • :>>>>>>> .n 的回调必须异步执行!怎么说呢,这是保证执行顺序的一致性和可预测性..
  • <="" font-weight="" promise?="" style=">为什么要特殊处理如果" value="" 是另一个="">.n 链中的 Promises 需要"展开" - 不然会出现嵌套的 Promises..
  • <="" font-weight="" onfulfilledcallbacks?="" style=">为什么要遍历">.n 怎么链式工作的关键!每次状态改变都需要通知所有等待中的 callbacks..

    "" _resolve="" n="" callback="" onrejected="">// ...
    if {
    setTimeout => handleCallback,0);} else if {
    setTimeout => handleCallback,0);} else { // pending state
    this.onFulfilledCallbacks.push;}
    return new MiniPromise => {
    // ...
    });}
    

      什么让 .n="" green;"="" style="color:" 能够链式调用?<="">每次 -="" .n="" .n="" :><="" <=""

      注意!这几行代码解释了 async="" await="" 背后运作原理: 注意!这几行代码解释了> javascript const handleCallback = callback?=> tryResolve) : => tryResolve;// ... tryResolve { /* ... */ } 这就是 await xxx 本质上是在做什么!

      5. 常见静态方法简化版实现: 5.>

      javascript static resolve { return new MiniPromise(resolve => resolve );}

      static all { return new MiniPromise => promises.forEach(promise => promise.n.catch ) );}

      记住!所有静态方法都是基于主要机制之上的包装!不过,

      6. 写完之后我真正理解了: 6.>

        const promiseA = fetch .n .catch;

        // 在其他地方... promiseA.n

        上面代码中,第二个 n 能够接收到第一个 n 中抛出错误吗?现在你明白了吧,怎么说呢,

      每次>
      什么让>

。

标签:写了
不过,

话说回来

至于前言。为什么重写 MiniPromise 才是理解异步编程的终极利器?老实说,

你是不是也曾这样痛苦过?

为了深入理解Promise,我重写的MiniPromise,能成为理解异步编程的终极利器吗?
  • 面试被问手写 Promise,只能机械地复制粘贴代码,但还是搞不懂原理
  • 看 Promise/A+ 规范。看了一遍又一遍却还是云里雾里
  • .n、Promise.all、async/await...这些概念在脑海中永远是支离破碎的知识点

这篇文章不打算直接贴完整代码。而是带你通过最小可行的 MiniPromise,从零理解 Promise 的设计思路。怎么说呢,

1. 先想清楚:Promise 本质上解决什么问题?

在 Promise 出现之前,我们用回调函数处理异步:


fetchData {
// ...回调地狱
})))));

痛点一:回调地狱不仅仅是嵌套难读!

  • 错误处理分散到各个层级,难以统一管理
  • 状态不可控 - 每个回调都可能修改全局状态导致难以维护
  • 业务逻辑被拆分到不同层级。可读性极差

Promise 的主要思路就两点: 1. 状态机模型 2. 链式调用返回新的Promise)

2. MiniPromise 的主要结构揭秘:仅需3个属性就能实现!


class MiniPromise {
constructor {
this.state = 'pending';// 初始状态
this.value = undefined;// 暂存结果
this.onFulfilledCallbacks =;// 满足时回调队列
this.onRejectedCallbacks =;// 拒绝时回调队列
const resolve = value => this._resolve;const reject = reason => this._reject;try {
executor;// 开始执行任务
} catch {
reject;按理说,}
}
}

⚠️ 注意!这里才是所有魔法的关键,⚠️

为什么只有4个主要属性就能实现完整功能?因为本质上 Promise 是一个有限状态机 + 异步任务管理器!

为了深入理解Promise,我重写的MiniPromise,能成为理解异步编程的终极利器吗?

_resolve {
if return;if { // 特殊处理情况
return value.n(
this._resolve.bind,this._reject.bind
);}
setTimeout => { // 必须异步执行!this.state = 'fulfilled';this.value = value;
this.onFulfilledCallbacks.forEach);},0),}

  • 为什么要检查当前状态不是 pending?: Avoid double resolution - 一旦转移了状态就不能再变了;,;,;,;,.>.>.>.>.>.>.>.>.>.
  • :>>>>>>> .n 的回调必须异步执行!怎么说呢,这是保证执行顺序的一致性和可预测性..
  • <="" font-weight="" promise?="" style=">为什么要特殊处理如果" value="" 是另一个="">.n 链中的 Promises 需要"展开" - 不然会出现嵌套的 Promises..
  • <="" font-weight="" onfulfilledcallbacks?="" style=">为什么要遍历">.n 怎么链式工作的关键!每次状态改变都需要通知所有等待中的 callbacks..

    "" _resolve="" n="" callback="" onrejected="">// ...
    if {
    setTimeout => handleCallback,0);} else if {
    setTimeout => handleCallback,0);} else { // pending state
    this.onFulfilledCallbacks.push;}
    return new MiniPromise => {
    // ...
    });}
    

      什么让 .n="" green;"="" style="color:" 能够链式调用?<="">每次 -="" .n="" .n="" :><="" <=""

      注意!这几行代码解释了 async="" await="" 背后运作原理: 注意!这几行代码解释了> javascript const handleCallback = callback?=> tryResolve) : => tryResolve;// ... tryResolve { /* ... */ } 这就是 await xxx 本质上是在做什么!

      5. 常见静态方法简化版实现: 5.>

      javascript static resolve { return new MiniPromise(resolve => resolve );}

      static all { return new MiniPromise => promises.forEach(promise => promise.n.catch ) );}

      记住!所有静态方法都是基于主要机制之上的包装!不过,

      6. 写完之后我真正理解了: 6.>

        const promiseA = fetch .n .catch;

        // 在其他地方... promiseA.n

        上面代码中,第二个 n 能够接收到第一个 n 中抛出错误吗?现在你明白了吧,怎么说呢,

      每次>
      什么让>

。

标签:写了