JavaScript Generators: A Comprehensive Overview

Apr 30, 2023 ・🕒 3 min read
What is Generators:
Generators are functions that can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances. – MDN.
Things to know about Generators:
- Generator is a special type of function that can be paused and resumed at any time.
- They’re created using the
function*
syntax. When a generator is created, the code inside it isn’t executed immediately. Instead, the code is generated into a sequence of values that you can access by using a loop or accessing one at a time using thenext()
method. - You can use
for...of
loop (orwhile
or loops) to iterate over their values. next()
method is used to resume the execution of a generator and get the next value. It returns an object with two properties:value
: which is the value returned by theyield
statement, anddone
: (Boolean value), indicates whether the generator has completed its execution.
Simple Example:
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
const generate = myGenerator();
console.log(generate.next().value); // 1
console.log(generate.next().value); // 2
console.log(generate.next().value); // 3
console.log(generate.next().value); // undefined // there are no more values to yield from myGenerator
`yield` keyword:
The yield
keyword is similar to the return
statement which terminates a function. However, instead of exiting out of the function, yield
suspends/pauses the execution context of the generator (thus allowing the function to continue running in the background until it is resumed by calling its next()
method again), besides returning the specified value.
Pause a function:
A paused function can create a closure, which is a block of code that has been temporarily stopped at a certain point in its execution, but it can also retain the position of that function so it can be resumed back and continue running.
Can we use return statement inside a Generator?
function* anotherGenerator() {
yield 1;
yield 2;
yield 3;
return 4;
}
const generate = anotherGenerator();
console.log(generate.next()); // { value: 1, done: false }
console.log(generate.next()); // { value: 2, done: false }
console.log(generate.next()); // { value: 3, done: false }
console.log(generate.next()); // { value: 4, done: true } // using return
console.log(generate.next()); // { value: undefined, done: true }
Generators VS Functions:

Benefits:
- Control the flow: Dynamic control over our functions: we can literally control the execution of our functions at any point during its iteration.
- Call by need: It is a way of evaluating expressions only when it is used/needed.
- Memory Efficient: The ability to use the minimum amount of memory necessary to accomplish a particular task.
Use-cases:
Generators can be useful when you want to produce a sequence of values without storing all of them in memory. Here are some particular use-cases: iterating over complex data structures, producing large data sets, generating infinite sequences...