export type CancelablePromise<T> = Promise<T> & {
    cancel: () => void;
};
 
const cancelSymbol = Symbol('cancel');
 
export function promiseCancelable<T>(prom: Promise<T>): CancelablePromise<T> {
    let reject: (reason?: any) => void;
    const cancelPromise = new Promise<T>((_, rej) => (reject = rej));
    const p = Promise.race([prom, cancelPromise]) as CancelablePromise<T>;
    p.cancel = () => reject(cancelSymbol);
    return p;
}
 
export function promiseIsCancel(reason?: any): boolean {
    return reason === cancelSymbol;
}

使用:

const cancelP = TaskCancelable(p);
 
cancelP
  .then((res) => {
    console.log("获取结果:", res);
  })
  .catch((reason) => {
    if (promiseIsCancel(reason)) {
      console.log("promise 被主动 cancel 了");
    } else {
      console.log("捕获到业务异常:", reason);
    }
  })
 
// 主动 cancel
cancelP.cancel()