How does a loop know when to stop asking for values? Each call to an iterator’s next() returns a result containing a value and a done property. When done is true, iteration has finished; spread and for..of stop calling next(). section 23.4
A generator pauses, then finishes
A generator that yields 'a' and then 'b' produces { value: 'a', done: false } on its first next() call and { value: 'b', done: false } on its second. The next call reaches the end and produces { value: undefined, done: true }. A yield pauses execution; done: true means there is no more code to execute. If the generator instead returns a value at the end, that final result can contain it. section 18.2
function primesIterator () {
const primes = [2, 3, 5]
return {
next() {
const value = primes.shift()
const done = !value
return {
value,
done
}
}
}
}
This hand-written iterator takes 2, 3, and 5 from an array, one per call. After the array is empty, its next() method sets done to true. section 23.4
An iterator can keep producing values indefinitely without setting done to true. Avoid collecting all its values with spread or consuming it with for..of: neither will finish. For practice, write a take(n, iterable) function that collects at most n values and also stops early when done becomes true. section 23.4 section 23.5
