mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-01-12 15:29:00 +08:00
* feat: pnpm new * Refactor build and release workflows, update dependencies Switch build scripts and workflows from npm to pnpm, update build and artifact paths, and simplify release workflow by removing version detection and changelog steps. Add new dependencies (silk-wasm, express, ws, node-pty-prebuilt-multiarch), update exports in package.json files, and add vite config for napcat-framework. Also, rename manifest.json for framework package and fix static asset copying in shell build config.
80 lines
2.1 KiB
TypeScript
80 lines
2.1 KiB
TypeScript
export type TaskExecutor<T> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void, onCancel: (callback: () => void) => void) => void | Promise<void>;
|
|
|
|
export class CancelableTask<T> {
|
|
private promise: Promise<T>;
|
|
private cancelCallback: (() => void) | null = null;
|
|
private isCanceled = false;
|
|
private cancelListeners: Array<() => void> = [];
|
|
|
|
constructor (executor: TaskExecutor<T>) {
|
|
this.promise = new Promise<T>((resolve, reject) => {
|
|
const onCancel = (callback: () => void) => {
|
|
this.cancelCallback = callback;
|
|
};
|
|
|
|
const execute = async () => {
|
|
try {
|
|
await executor(
|
|
(value) => {
|
|
if (!this.isCanceled) {
|
|
resolve(value);
|
|
}
|
|
},
|
|
(reason) => {
|
|
if (!this.isCanceled) {
|
|
reject(reason);
|
|
}
|
|
},
|
|
onCancel
|
|
);
|
|
} catch (error) {
|
|
if (!this.isCanceled) {
|
|
reject(error);
|
|
}
|
|
}
|
|
};
|
|
|
|
execute();
|
|
});
|
|
}
|
|
|
|
public cancel () {
|
|
if (this.cancelCallback) {
|
|
this.cancelCallback();
|
|
}
|
|
this.isCanceled = true;
|
|
this.cancelListeners.forEach(listener => listener());
|
|
}
|
|
|
|
public isTaskCanceled (): boolean {
|
|
return this.isCanceled;
|
|
}
|
|
|
|
public onCancel (listener: () => void) {
|
|
this.cancelListeners.push(listener);
|
|
}
|
|
|
|
public then<TResult1 = T, TResult2 = never>(
|
|
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
|
|
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
|
|
): Promise<TResult1 | TResult2> {
|
|
return this.promise.then(onfulfilled, onrejected);
|
|
}
|
|
|
|
public catch<TResult = never>(
|
|
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null
|
|
): Promise<T | TResult> {
|
|
return this.promise.catch(onrejected);
|
|
}
|
|
|
|
public finally (onfinally?: (() => void) | undefined | null): Promise<T> {
|
|
return this.promise.finally(onfinally);
|
|
}
|
|
|
|
[Symbol.asyncIterator] () {
|
|
return {
|
|
next: () => this.promise.then(value => ({ value, done: true })),
|
|
};
|
|
}
|
|
}
|