Tools
Tools: JavaScript Generators and Iterators: A Practical Guide
2026-02-27
0 views
admin
The Core Concept ## Infinite Sequences ## Lazy Evaluation ## Two-Way Communication ## Async Generators ## Generator-Based State Machine ## Real-World: Redux-Saga Pattern Generators are one of JavaScript's most underused features. Once you understand them, you'll find uses everywhere. A generator function can pause and resume. It yields values one at a time. The * makes it a generator. yield is the pause point. Process huge datasets without loading them all into memory: You can send values INTO a generator: Combine generators with async/await for streaming data: Generators power redux-saga for complex async flows: The testability is excellent — you can test each yield step in isolation without making real API calls. Use the JavaScript Minifier to optimize your generator code for production. Full generators guide at viadreams.cc/en/blog/javascript-generators-guide Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to ? It will become hidden in your post, but will still be visible via the comment's permalink. as well , this person and/or CODE_BLOCK: function* counter() { let n = 0; while (true) { yield n++; // Pause here, return n, resume on next call } } const gen = counter(); gen.next(); // { value: 0, done: false } gen.next(); // { value: 1, done: false } gen.next(); // { value: 2, done: false } // Infinite sequence, no memory issues CODE_BLOCK: function* counter() { let n = 0; while (true) { yield n++; // Pause here, return n, resume on next call } } const gen = counter(); gen.next(); // { value: 0, done: false } gen.next(); // { value: 1, done: false } gen.next(); // { value: 2, done: false } // Infinite sequence, no memory issues CODE_BLOCK: function* counter() { let n = 0; while (true) { yield n++; // Pause here, return n, resume on next call } } const gen = counter(); gen.next(); // { value: 0, done: false } gen.next(); // { value: 1, done: false } gen.next(); // { value: 2, done: false } // Infinite sequence, no memory issues CODE_BLOCK: function* fibonacci() { let [a, b] = [0, 1]; while (true) { yield a; [a, b] = [b, a + b]; } } // Take first 10 Fibonacci numbers function take(gen, n) { const result = []; for (const value of gen) { result.push(value); if (result.length === n) break; } return result; } take(fibonacci(), 10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] CODE_BLOCK: function* fibonacci() { let [a, b] = [0, 1]; while (true) { yield a; [a, b] = [b, a + b]; } } // Take first 10 Fibonacci numbers function take(gen, n) { const result = []; for (const value of gen) { result.push(value); if (result.length === n) break; } return result; } take(fibonacci(), 10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] CODE_BLOCK: function* fibonacci() { let [a, b] = [0, 1]; while (true) { yield a; [a, b] = [b, a + b]; } } // Take first 10 Fibonacci numbers function take(gen, n) { const result = []; for (const value of gen) { result.push(value); if (result.length === n) break; } return result; } take(fibonacci(), 10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] CODE_BLOCK: function* processLargeFile(lines) { for (const line of lines) { if (line.startsWith('#')) continue; // Skip comments const [key, value] = line.split('='); yield { key: key.trim(), value: value.trim() }; } } // Only processes lines as needed - doesn't load 10GB into memory for (const entry of processLargeFile(readFileLines('huge-config.txt'))) { if (entry.key === 'TARGET_KEY') { console.log(entry.value); break; // Stops reading the file } } CODE_BLOCK: function* processLargeFile(lines) { for (const line of lines) { if (line.startsWith('#')) continue; // Skip comments const [key, value] = line.split('='); yield { key: key.trim(), value: value.trim() }; } } // Only processes lines as needed - doesn't load 10GB into memory for (const entry of processLargeFile(readFileLines('huge-config.txt'))) { if (entry.key === 'TARGET_KEY') { console.log(entry.value); break; // Stops reading the file } } CODE_BLOCK: function* processLargeFile(lines) { for (const line of lines) { if (line.startsWith('#')) continue; // Skip comments const [key, value] = line.split('='); yield { key: key.trim(), value: value.trim() }; } } // Only processes lines as needed - doesn't load 10GB into memory for (const entry of processLargeFile(readFileLines('huge-config.txt'))) { if (entry.key === 'TARGET_KEY') { console.log(entry.value); break; // Stops reading the file } } CODE_BLOCK: function* calculator() { let result = 0; while (true) { const input = yield result; // Send current result out, wait for input result += input; } } const calc = calculator(); calc.next(); // Start: { value: 0, done: false } calc.next(10); // Add 10: { value: 10, done: false } calc.next(5); // Add 5: { value: 15, done: false } calc.next(-3); // Subtract 3: { value: 12, done: false } CODE_BLOCK: function* calculator() { let result = 0; while (true) { const input = yield result; // Send current result out, wait for input result += input; } } const calc = calculator(); calc.next(); // Start: { value: 0, done: false } calc.next(10); // Add 10: { value: 10, done: false } calc.next(5); // Add 5: { value: 15, done: false } calc.next(-3); // Subtract 3: { value: 12, done: false } CODE_BLOCK: function* calculator() { let result = 0; while (true) { const input = yield result; // Send current result out, wait for input result += input; } } const calc = calculator(); calc.next(); // Start: { value: 0, done: false } calc.next(10); // Add 10: { value: 10, done: false } calc.next(5); // Add 5: { value: 15, done: false } calc.next(-3); // Subtract 3: { value: 12, done: false } CODE_BLOCK: async function* streamPages(url) { let page = 1; while (true) { const response = await fetch(`${url}?page=${page}`); const data = await response.json(); if (data.items.length === 0) return; yield* data.items; // Yield each item individually page++; } } // Process API results as they stream in for await (const user of streamPages('/api/users')) { await processUser(user); } CODE_BLOCK: async function* streamPages(url) { let page = 1; while (true) { const response = await fetch(`${url}?page=${page}`); const data = await response.json(); if (data.items.length === 0) return; yield* data.items; // Yield each item individually page++; } } // Process API results as they stream in for await (const user of streamPages('/api/users')) { await processUser(user); } CODE_BLOCK: async function* streamPages(url) { let page = 1; while (true) { const response = await fetch(`${url}?page=${page}`); const data = await response.json(); if (data.items.length === 0) return; yield* data.items; // Yield each item individually page++; } } // Process API results as they stream in for await (const user of streamPages('/api/users')) { await processUser(user); } COMMAND_BLOCK: function* trafficLight() { while (true) { yield 'green'; // 30 seconds yield 'yellow'; // 5 seconds yield 'red'; // 30 seconds } } const light = trafficLight(); setInterval(() => { const { value } = light.next(); updateLight(value); }, 5000); COMMAND_BLOCK: function* trafficLight() { while (true) { yield 'green'; // 30 seconds yield 'yellow'; // 5 seconds yield 'red'; // 30 seconds } } const light = trafficLight(); setInterval(() => { const { value } = light.next(); updateLight(value); }, 5000); COMMAND_BLOCK: function* trafficLight() { while (true) { yield 'green'; // 30 seconds yield 'yellow'; // 5 seconds yield 'red'; // 30 seconds } } const light = trafficLight(); setInterval(() => { const { value } = light.next(); updateLight(value); }, 5000); CODE_BLOCK: function* fetchUserSaga(action) { try { yield put({ type: 'FETCH_START' }); const user = yield call(fetchUser, action.userId); // Pausable async call yield put({ type: 'FETCH_SUCCESS', payload: user }); } catch (error) { yield put({ type: 'FETCH_ERROR', error }); } } CODE_BLOCK: function* fetchUserSaga(action) { try { yield put({ type: 'FETCH_START' }); const user = yield call(fetchUser, action.userId); // Pausable async call yield put({ type: 'FETCH_SUCCESS', payload: user }); } catch (error) { yield put({ type: 'FETCH_ERROR', error }); } } CODE_BLOCK: function* fetchUserSaga(action) { try { yield put({ type: 'FETCH_START' }); const user = yield call(fetchUser, action.userId); // Pausable async call yield put({ type: 'FETCH_SUCCESS', payload: user }); } catch (error) { yield put({ type: 'FETCH_ERROR', error }); } }
toolsutilitiessecurity toolsjavascriptgeneratorsiteratorspracticalguide