-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Description
import React, { useState, useCallback } from "react";
import useAsyncQueue from "use-async-queue";
// Constants
const concurrency = 2;
const urlBase = "https://reqres.in/api/users?page=";
const EmailQueue = () => {
const [itemId, setItemId] = useState(1);
const [cache, setCache] = useState<Record<number, string>>({});
const [numBatchesFinished, setNumBatchesFinished] = useState(0);
// Simulate inflight status
const inflight = useCallback(
({ id }: { id: number }) => {
setCache((c) => ({ ...c, [id]: "inflight" }));
},
[setCache]
);
// Simulate completion of task and processing result
const done = useCallback(
({ id, result }: { id: number; result: Promise<string> }) => {
result
.then((body) => {
setCache((c) => ({
...c,
[id]: body.slice(0, 100) + "...", // Only show part of the result
}));
})
.catch((error) => {
setCache((c) => ({
...c,
[id]: "error: " + error.message,
}));
});
},
[setCache]
);
// Handle when a batch of tasks finishes
const drain = useCallback(
() => setNumBatchesFinished((n) => n + 1),
[setNumBatchesFinished]
);
// Initialize the async queue with the required settings
const queue = useAsyncQueue({
concurrency,
inflight,
done,
drain,
});
// Stats from the async queue
const { numInFlight, numPending, numDone } = queue.stats;
// Fake async task function
const fetchNextItem = () => {
const task = {
id: itemId,
task: (): Promise<string> => {
return new Promise((resolve) => {
setTimeout(() => {
// Fake task: returning a string as result after 1 second
resolve(`Fetched item ${itemId}`);
}, 1000);
});
},
};
queue.add(task);
setItemId((n) => n + 1); // Increment itemId for the next task
};
return (
<>
<h1>Async Queue Demo</h1>
<button onClick={fetchNextItem}>Fetch item {itemId}</button>
<p>numInFlight will never be greater than concurrency ({concurrency}).</p>
{["numPending", "numInFlight", "numDone"].map((metric) => (
<span key={metric}>
{metric}: {eval(metric)}{" "}
</span>
))}
<span>numBatchesFinished: {numBatchesFinished}</span>
<table>
<thead>
<tr>
<td>Item</td>
<td>Status</td>
</tr>
</thead>
<tbody>
{"x"
.repeat(itemId - 1)
.split("")
.map((_, idx: number) => {
const id = idx + 1;
return (
<tr key={"item" + id}>
<td>Item {id}</td>
<td>{cache[id] ? cache[id] : "pending"}</td>
</tr>
);
})}
</tbody>
</table>
</>
);
};
export default EmailQueue;
Metadata
Metadata
Assignees
Labels
No labels