javascript / intermediate
Snippet
Controlling Asynchronous Polling Streams with Async Generators in React
Async generator functions (`async function*`) offer a clean control-flow mechanism to produce streams of values over time. In React effects, consuming an async generator with a `for await...of` loop simplifies conditional polling logic and allows clean cancellation when dependencies change or the component unmounts.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { useState, useEffect } from 'react';async function* pollStatus(jobId, intervalMs = 2000) {while (true) {const res = await fetch(`/api/jobs/${jobId}`);const data = await res.json();yield data;if (data.status === 'completed' || data.status === 'failed') break;await new Promise((resolve) => setTimeout(resolve, intervalMs));}}export function JobTracker({ jobId }) {const [job, setJob] = useState(null);useEffect(() => {let isCancelled = false;const generator = pollStatus(jobId);async function consume() {for await (const update of generator) {if (isCancelled) break;setJob(update);}}consume();return () => { isCancelled = true; };}, [jobId]);return <div>Status: {job ? job.status : 'Connecting...'}</div>;}
react
Breakdown
1
async function* pollStatus(jobId, intervalMs = 2000) {
Declares an async generator that can yield streamed responses and pause execution between iterations.
2
yield data;
Emits the latest fetched payload to the consumer without terminating the generator loop.
3
for await (const update of generator) {
Iterates asynchronously over each value produced by the generator as promises resolve.