Skip to content
Astera Technology

Generate values only when iteration asks for them

Count the work performed by two next calls on a finite generator.

Download complete case notes and answer keys ↓

Trace the fixed program

The generator contains three fixed labels. Creating the iterator does not visit any label; call next twice and inspect visited.

Complete original program
let visited=0;
function* labels(){for(const label of ['Markup','Layout','Scripting']){visited++;yield label;}}
const iterator=labels();const before=visited;const first=iterator.next();const second=iterator.next();
console.log(JSON.stringify({before,first,second,visited}));
Exact console output
{"before":0,"first":{"value":"Markup","done":false},"second":{"value":"Layout","done":false},"visited":2}
Values and execution
ActionReturned recordvisited
labels()Iterator only0
first next(){value:"Markup",done:false}1
second next(){value:"Layout",done:false}2

Explain the result

Calling the generator creates an iterator without running its body. next resumes until the next yield, which suspends execution. Two calls visit two labels. A final next after the last yield completes the generator; JSON omits its undefined value field.

Test the alternative

Spreading the iterator consumes every remaining value. A copied array requires the work up front; it no longer offers the original lazy pause points.

Separate finite alternative
let visited=0;function* labels(){for(const label of ['Markup','Layout','Scripting']){visited++;yield label;}}
const iterator=labels();const first=iterator.next();const rest=[...iterator];
console.log(JSON.stringify({first,rest,visited}));
Alternative output
{"first":{"value":"Markup","done":false},"rest":["Layout","Scripting"],"visited":3}

Work the boundary case

After two next calls, what do the third and fourth calls return?

Show the worked answer

Third yields Scripting with done:false; fourth completes with value:undefined and done:true. visited stays 3.

Fresh boundary program
let visited=0;function* labels(){for(const label of ['Markup','Layout','Scripting']){visited++;yield label;}}
const iterator=labels();iterator.next();iterator.next();const third=iterator.next();const fourth=iterator.next();
console.log(JSON.stringify({third,fourth,finalValueType:typeof fourth.value,visited}));
Boundary output
{"third":{"value":"Scripting","done":false},"fourth":{"done":true},"finalValueType":"undefined","visited":3}

Original example files