2023-03-23 20:09:00 +08:00
|
|
|
export interface CancelAction {
|
2023-04-18 23:08:49 +08:00
|
|
|
/**
|
|
|
|
* 取消信息
|
|
|
|
*/
|
|
|
|
(message?: string): void;
|
2023-03-23 20:09:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface CancelExecutor {
|
2023-04-18 23:08:49 +08:00
|
|
|
(cancel: CancelAction): void;
|
2023-03-23 20:09:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface CancelTokenSource {
|
2023-04-06 15:16:12 +08:00
|
|
|
/**
|
|
|
|
* 取消令牌
|
|
|
|
*/
|
2023-03-23 20:09:00 +08:00
|
|
|
token: CancelToken;
|
2023-04-06 15:16:12 +08:00
|
|
|
/**
|
|
|
|
* 取消函数
|
|
|
|
*/
|
2023-03-23 20:09:00 +08:00
|
|
|
cancel: CancelAction;
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface CancelTokenConstructor {
|
|
|
|
new (executor: CancelExecutor): CancelToken;
|
|
|
|
source(): CancelTokenSource;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Cancel {
|
2023-04-06 16:00:04 +08:00
|
|
|
message?: string;
|
2023-03-23 20:09:00 +08:00
|
|
|
|
2023-04-06 16:00:04 +08:00
|
|
|
constructor(message?: string) {
|
2023-03-23 20:09:00 +08:00
|
|
|
this.message = message;
|
|
|
|
}
|
|
|
|
|
2023-04-06 16:00:04 +08:00
|
|
|
toString(): string {
|
2023-03-23 20:09:00 +08:00
|
|
|
const message = this.message ? `: ${this.message}` : '';
|
|
|
|
|
|
|
|
return `Cancel${message}`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isCancel(value: unknown): value is Cancel {
|
|
|
|
return value instanceof Cancel;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class CancelToken {
|
2023-04-06 16:00:04 +08:00
|
|
|
#reason?: Cancel;
|
2023-03-23 20:09:00 +08:00
|
|
|
|
2023-05-14 21:44:08 +08:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
2023-04-06 16:00:04 +08:00
|
|
|
onCancel: Promise<Cancel>['then'];
|
2023-03-23 20:09:00 +08:00
|
|
|
|
2023-04-06 16:00:04 +08:00
|
|
|
constructor(executor: CancelExecutor) {
|
2023-03-23 20:09:00 +08:00
|
|
|
let action!: CancelAction;
|
2023-03-29 22:23:36 +08:00
|
|
|
const promise = new Promise<Cancel>((resolve) => {
|
2023-03-23 20:09:00 +08:00
|
|
|
action = (message) => {
|
2023-04-06 16:00:04 +08:00
|
|
|
if (this.#reason) {
|
2023-03-23 20:09:00 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-04-06 16:00:04 +08:00
|
|
|
this.#reason = new Cancel(message);
|
2023-03-23 20:09:00 +08:00
|
|
|
|
2023-04-06 16:00:04 +08:00
|
|
|
resolve(this.#reason);
|
2023-03-23 20:09:00 +08:00
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2023-03-29 22:23:36 +08:00
|
|
|
this.onCancel = promise.then.bind(promise);
|
|
|
|
|
2023-03-23 20:09:00 +08:00
|
|
|
executor(action);
|
|
|
|
}
|
|
|
|
|
2023-04-06 16:00:04 +08:00
|
|
|
static source(): CancelTokenSource {
|
2023-03-23 20:09:00 +08:00
|
|
|
let cancel!: CancelAction;
|
|
|
|
const token = new CancelToken((action) => {
|
|
|
|
cancel = action;
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
token,
|
|
|
|
cancel,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-05-14 21:44:08 +08:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
2023-04-06 16:00:04 +08:00
|
|
|
throwIfRequested(): void {
|
|
|
|
if (this.#reason) {
|
|
|
|
throw this.#reason;
|
2023-03-23 20:09:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isCancelToken(value: unknown): value is CancelToken {
|
|
|
|
return value instanceof CancelToken;
|
|
|
|
}
|