Skip to content

Instantly share code, notes, and snippets.

@Looskie
Last active September 26, 2023 23:07
Show Gist options
  • Save Looskie/1856cf8a13b21015d43be7395a012b3c to your computer and use it in GitHub Desktop.
Save Looskie/1856cf8a13b21015d43be7395a012b3c to your computer and use it in GitHub Desktop.
A react hook job queuing mini micro little guy :D
import { createRef, useEffect, useImperativeHandle, useState } from "react";
type Job<T = unknown> = {
task: () => Promise<T> | T;
};
function useQueue(finallyCallback?: () => void) {
const [executing, setExecuting] = useState(false);
const [jobs, setJobs] = useState<Array<Job>>([]);
const queueRef = createRef<{
jobsLength: number;
executing: boolean;
setExecuting: (executing: boolean) => void;
addJob: (job: Job) => void;
shiftJobs: () => void;
}>();
useEffect(() => {
const run = async () => {
if (jobs.length === 0) return;
setExecuting(true);
const job = jobs[0];
await job.task();
shiftJobs();
setExecuting(false);
};
run();
return () => {
if (jobs.length === 1 && finallyCallback) {
finallyCallback();
}
};
}, [jobs.length]);
const addJob = (job: Job) => {
setJobs((prev) => [...prev, job]);
};
const shiftJobs = () => {
setJobs((prev) => prev.slice(1));
};
useImperativeHandle(
queueRef,
() => ({
executing,
setExecuting,
jobsLength: jobs.length,
addJob,
shiftJobs,
}),
[jobs.length, executing]
);
return queueRef;
}
export default useQueue;
@Looskie
Copy link
Author

Looskie commented Sep 19, 2023

@Looskie damn this is cool, thanks

@Looskie
Copy link
Author

Looskie commented Sep 26, 2023

for anyone reviewing this, this is like half finished so if you plan to use it beware you might have to write some extra code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment