一、 为什么 Promise 无法直接“杀死”?
- Promise 的局限性:一旦状态从
pending变为fulfilled或rejected,过程不可逆。 - 应用场景:用户频繁切换 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));