Skip to content

Instantly share code, notes, and snippets.

@nemolize
Created July 16, 2024 18:01
Show Gist options
  • Save nemolize/620349efe4f61b96d2adb848b81dfd23 to your computer and use it in GitHub Desktop.
Save nemolize/620349efe4f61b96d2adb848b81dfd23 to your computer and use it in GitHub Desktop.
const MAX_CONCURRENCY = 2;
const useTaskQueue = () => {
const triggers = useRef<Function[]>([]);
const runningTasksRef = useRef(new Set<Function>());
const dispatchTriggers = useCallback(() => {
const runningTaskSize = runningTasksRef.current.size;
if (runningTaskSize >= MAX_CONCURRENCY) return;
const newTaskSize = MAX_CONCURRENCY - runningTaskSize;
const newTriggers = triggers.current.splice(0, newTaskSize);
newTriggers.forEach((trigger) => trigger());
}, []);
const queueTask = useCallback(
async <T extends () => any>(
task: T
): Promise<ReturnType<T> extends infer U extends Promise<any> ? Awaited<U> : ReturnType<T>> => {
await new Promise<void>((resolve) => {
const resolver = () => {
runningTasksRef.current.add(task);
resolve();
};
triggers.current.push(resolver);
dispatchTriggers();
});
const res = await task();
runningTasksRef.current.delete(task);
dispatchTriggers();
return res;
},
[dispatchTriggers]
);
return { queueTask };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment