A generator is a special function that produces a sequence of values over time instead of returning one value. Calling a generator function returns a Generator object, which is both iterable and an iterator. Each next() call resumes execution and returns { value, done }. section 9.2 section 9.2.1
Yielding several values
function* sayIt() { yield 'The'; yield 'Joy'; yield 'of'; yield 'JavaScript!'; } for (const message of sayIt()) { console.log(message); } The generator pauses at each yield, and for...of consumes the resulting iterable.
The asterisk identifies generator functions and generator methods. Unlike ordinary functions, they return an iterator-producing object immediately; yield supplies successive values, while return ends the iteration. Generator arrow functions are not supported in the described syntax. section 9.2.1
Generators support practical patterns for controlled and composable value production:
- Create arbitrary amounts of data lazily, such as repeatedly constructing blockchain blocks until the consumer stops. section 9.2.2
- Make domain objects iterable by implementing Symbol.iterator, then use spread or destructuring to expose selected states or properties. section 9.2.2
- Bridge generators into push-based observables so yielded values can flow through mapping, filtering, reduction, and subscription. section 9.4.5
Listing 9.8 Async generator that sends blocks read from a file
async function* generateBlocksFromFile(file) { #1
try {
await fsp.access(file, fs.constants.F_OK | fs.constants.R_OK);
const dataStream = fs.createReadStream(file,
{ encoding: 'utf8', highWaterMark: 64 });
let previousDecodedData = '';
for await (const chunk of dataStream) {
previousDecodedData += chunk;
let separatorIndex;
while ((separatorIndex = previousDecodedData.indexOf(';')) >= 0) {
const decodedData = previousDecodedData.slice(0,
separatorIndex + 1);
const blocks = tokenize(';', decodedData)
.filter(str => str.length > 0)
.map(str => str.replace(';', ''));
for (const block of blocks) {
yield JSON.parse(block); #2
}
previousDecodedData = previousDecodedData.slice(
separatorIndex + 1);
}
}
if (previousDecodedData.length > 0) {
yield JSON.parse(previousDecodedData); #2
}
}
catch (e) {
console.error(`Error processing file: ${e.message}`);
throw e;
}
}
An async generator reads file data incrementally and yields parsed blocks, demonstrating generators as moving-window stream processors. section 9.2.3
An async generator yields promises rather than immediately available values and is consumed with for await...of. This model processes asynchronous data in chunks, avoiding the need to load an entire file before validating its contents. section 9.2.3











