import { useMemo } from 'react';
import { useUnmount } from './useUnmount';
class AsyncInstance {
protected clearFns = new Set<() => void>();
clearAll() {
for (const clear of this.clearFns) {
clear();
}
}
setTimeout(handler: TimerHandler, timeout?: number, clearFn?: () => void) {
const tid = window.setTimeout(handler, timeout);
const clear = () => {
clearFn?.();
clearTimeout(tid);
};
this.clearFns.add(clear);
return clear;
}
requestAnimationFrame(cb: FrameRequestCallback, clearFn?: () => void) {
const tid = requestAnimationFrame(cb);
const clear = () => {
clearFn?.();
cancelAnimationFrame(tid);
};
this.clearFns.add(clear);
return clear;
}
}
export class Async extends AsyncInstance {
private instances = new Set<AsyncInstance>();
create(): AsyncInstance {
const instance = new AsyncInstance();
this.instances.add(instance);
return instance;
}
override clearAll() {
for (const clear of this.clearFns) {
clear();
}
for (const instance of this.instances) {
instance.clearAll();
}
}
}
export function useAsync(): Async {
const async = useMemo(() => new Async(), []);
useUnmount(() => {
async.clearAll();
});
return async;
}