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

如何实现JavaScript Promise的reRun方法以重执行所有thenable处理器?

实现可重跑的Promise(支持重新触发所有then/finally回调)

原生Promise一旦进入已完成(fulfilled)或已拒绝(rejected)状态就无法改变,因此无法直接让已绑定的then/finally回调重新执行。我们需要自定义一个继承原生Promise的类,通过保存执行逻辑和回调队列的方式实现reRun方法。

实现代码

class ReRunnablePromise extends Promise {
  constructor(executor) {
    super(executor);
    // 保存原始执行器逻辑
    this.executor = executor;
    // 存储所有绑定的then/finally回调
    this.callbacks = [];
  }

  // 重写then方法,保存回调后调用原生then
  then(onFulfilled, onRejected) {
    this.callbacks.push({
      type: 'then',
      onFulfilled: typeof onFulfilled === 'function' ? onFulfilled : undefined,
      onRejected: typeof onRejected === 'function' ? onRejected : undefined
    });
    return super.then(onFulfilled, onRejected);
  }

  // 重写finally方法,保存回调后调用原生finally
  finally(callback) {
    if (typeof callback === 'function') {
      this.callbacks.push({ type: 'finally', callback });
    }
    return super.finally(callback);
  }

  // 实现reRun方法:重新执行原始逻辑并触发所有回调
  reRun() {
    // 创建新的Promise实例,执行原始逻辑
    let currentPromise = new Promise(this.executor);
    // 依次绑定所有保存的回调
    for (const cb of this.callbacks) {
      if (cb.type === 'then') {
        currentPromise = currentPromise.then(cb.onFulfilled, cb.onRejected);
      } else if (cb.type === 'finally') {
        currentPromise = currentPromise.finally(cb.callback);
      }
    }
    // 返回新的Promise链,支持后续链式调用(可选)
    return currentPromise;
  }

  // 静态resolve方法,兼容原生Promise.resolve的使用方式
  static resolve(value) {
    return new ReRunnablePromise(resolve => resolve(value));
  }

  // 静态reject方法,同理
  static reject(reason) {
    return new ReRunnablePromise((_, reject) => reject(reason));
  }
}

使用示例

// 用自定义类创建可重跑的Promise
const promise = ReRunnablePromise.resolve(1);

// 绑定多个then和finally回调
promise.then(value => {
  console.log(value); // 第一次输出1
  return value + 1;
}).then(value => {
  console.log(value); // 第一次输出2
});

promise.finally(() => {
  console.log('finally回调触发'); // 第一次输出
});

// 调用reRun,重新触发所有回调
promise.reRun();
// 此时会再次输出:1、2、finally回调触发

核心逻辑说明

  • 继承原生Promise保证了所有原生Promise的特性(异步执行、链式调用、catch方法等)。
  • 每次调用then/finally时,会将回调函数存入内部队列,同时正常执行原生方法保持原有行为。
  • reRun方法会重新创建一个执行原始逻辑的Promise,然后将队列中所有回调依次绑定到新Promise上,从而让所有回调重新执行。
  • 对于异步的执行逻辑(比如包含setTimeout),每次reRun都会重新触发异步流程,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:25:37