从零实现 Promise 取消机制

6 阅读1分钟

一、 为什么 Promise 无法直接“杀死”?

  • Promise 的局限性:一旦状态从 pending 变为 fulfilledrejected,过程不可逆。
  • 应用场景:用户频繁切换 Tab、搜索框防抖、组件销毁时未返回的请求。

二、 核心思路:注入“外部控制权”

resolve 控制权交给了外部。

class CancelToken {
  constructor(cancelFn) {
    this.promise = new Promise((resolve) => {
      // 这里的 cancelFn 实际上是将 resolve 的能力暴露给了调用者
      cancelFn(resolve);
    });
  }
}

三、使用示例

<button id="start">Start</button>
<button id="cancel">Cancel</button>
const startButton = document.querySelector('#start');
const cancelButton = document.querySelector('#cancel');

function cancellableDelayedResolve(delay) {
 console.asyncLog("set delay");

  return new Promise((resolve, reject) => {
    const id = setTimeout((() => {
      console.asyncLog("delayed resolve");
      resolve();
    }), delay);

    const cancelToken = new CancelToken((cancelCallback) =>
      cancelButton.addEventListener("click", cancelCallback));

    cancelToken.promise.then(() => clearTimeout(id));
  });
}

startButton.addEventListener("click", () => cancellableDelayedResolve(1000));