You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中实现Promise?求提供具体实现示例

嘿,这个问题问到点子上了!要手动实现Promise,得先吃透它的核心规则:状态只能从pending转为fulfilled或rejected,一旦改变就再也不能变;then方法可以注册成功/失败的回调,还支持链式调用;异步操作的回调要能被正确触发。

我给你写一个符合Promise A+规范的简化版实现,每一步都加上注释,方便你理解:

手动实现Promise(简化版)
class MyPromise {
  // 定义三种核心状态
  static PENDING = 'pending';
  static FULFILLED = 'fulfilled';
  static REJECTED = 'rejected';

  constructor(executor) {
    // 初始化状态为pending
    this.status = MyPromise.PENDING;
    // 存储成功时的返回值
    this.value = null;
    // 存储失败时的错误原因
    this.reason = null;
    // 缓存异步场景下的成功回调(状态未改变时注册)
    this.onFulfilledCallbacks = [];
    // 缓存异步场景下的失败回调
    this.onRejectedCallbacks = [];

    // resolve函数:将状态转为fulfilled并触发回调
    const resolve = (value) => {
      // 只有pending状态能被修改
      if (this.status === MyPromise.PENDING) {
        this.status = MyPromise.FULFILLED;
        this.value = value;
        // 批量触发所有缓存的成功回调
        this.onFulfilledCallbacks.forEach(callback => callback());
      }
    };

    // reject函数:将状态转为rejected并触发回调
    const reject = (reason) => {
      if (this.status === MyPromise.PENDING) {
        this.status = MyPromise.REJECTED;
        this.reason = reason;
        // 批量触发所有缓存的失败回调
        this.onRejectedCallbacks.forEach(callback => callback());
      }
    };

    // 立即执行传入的executor函数,捕获同步错误
    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  // then方法:注册回调并返回新Promise实现链式调用
  then(onFulfilled, onRejected) {
    // 处理参数默认值:没传回调时做透传处理
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };

    // 返回新Promise,保证链式调用的独立性
    const promise2 = new MyPromise((resolve, reject) => {
      // 状态已为fulfilled时,直接执行成功回调
      if (this.status === MyPromise.FULFILLED) {
        // 用setTimeout模拟异步执行,符合Promise规范的微任务要求
        setTimeout(() => {
          try {
            const x = onFulfilled(this.value);
            // 处理回调返回值:如果是Promise则等待其完成,否则直接resolve
            this.resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }

      // 状态已为rejected时,直接执行失败回调
      if (this.status === MyPromise.REJECTED) {
        setTimeout(() => {
          try {
            const x = onRejected(this.reason);
            this.resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }

      // 状态还是pending时,将回调缓存起来
      if (this.status === MyPromise.PENDING) {
        this.onFulfilledCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onFulfilled(this.value);
              this.resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });

        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onRejected(this.reason);
              this.resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });
      }
    });

    return promise2;
  }

  // 处理then回调返回值的统一逻辑,符合Promise A+规范
  resolvePromise(promise2, x, resolve, reject) {
    // 避免循环引用
    if (promise2 === x) {
      return reject(new TypeError('Chaining cycle detected for promise'));
    }

    // 如果返回值是Promise实例,等待其状态变更
    if (x instanceof MyPromise) {
      x.then(resolve, reject);
    } else {
      // 普通值直接resolve
      resolve(x);
    }
  }

  // catch方法:语法糖,等价于then(null, onRejected)
  catch(onRejected) {
    return this.then(null, onRejected);
  }
}
测试我们的Promise实现

用一个模拟异步请求的场景来验证功能:

// 模拟异步接口请求
function fetchMockData() {
  return new MyPromise((resolve, reject) => {
    setTimeout(() => {
      // 随机模拟成功/失败
      const isSuccess = Math.random() > 0.5;
      if (isSuccess) {
        resolve('模拟请求成功:拿到用户数据');
      } else {
        reject('模拟请求失败:服务器超时');
      }
    }, 1000);
  });
}

// 使用自定义Promise
fetchMockData()
  .then(data => {
    console.log(data);
    return `加工后的数据:${data}`;
  })
  .then(processedData => {
    console.log(processedData);
  })
  .catch(error => {
    console.error('捕获到错误:', error);
  });

这个实现覆盖了Promise的核心特性:状态不可逆、异步回调触发、链式调用、错误捕获。标准Promise还有更多细节(比如all/race等静态方法、thenable对象处理),但这个简化版足够帮你理解底层逻辑啦~

内容的提问来源于stack exchange,提问作者Chandrashekhar Patidar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:51:07