What are JavaScript generators?

Generators are functions that can pause execution midway through and then continue from where they stopped.

A standard function in JavaScript runs until it ​returns or executes its last line of code. Invoking the function again causes it to begin execution from the start. In contrast, a Generator can stop midway and yield a return value. Invoking the Generator again resumes the execution from where it last left off.

The following illustration highlights this difference:

svg viewer

Syntax

A generator can be declared either of the following two ways:

function * myGenerator () {}
// or
let myGenerator = function * () {}

Code

Generators return an object that has two properties: value (the yielded value) and done (shows us whether or not the generator has finished its job). Consider the following code snippet where the done​ property becomes true once the generator has yielded all of its values: ​

function * generator() {
yield 5;
}
const gen = generator();
console.log(gen.next());
console.log(gen.next());

Generators are useful because, instead of returning all the values, a value is only yielded when it is needed​. The following example highlights this:

function * generator() {
let a = 5;
yield a + 1;
a = 10;
yield a + 5;
}
const gen = generator();
console.log(gen.next().value);
console.log("...Doing some other work after getting a yield...")
console.log(gen.next().value);

Generators also take arguments and are reusable:

function * generator(arg = 'Empty') {
yield arg;
}
const gen0 = generator();
console.log(gen0.next().value);
const gen1 = generator('Hi');
console.log(gen1.next().value);

Generators are iterable themselves; hence, they can be used to implement iterables with very few lines of code:

function * generator() {
yield 'This';
yield 'is';
yield 'iterable.'
}
for (const val of generator()) {
console.log(val);
}

Another very handy use case is that generators allow the creation of infinite data streams. In the example below, note how the generator is suspended after yielding a value from an infinite loop:

function * naturalNumbers() {
let num = 1;
while (true) {
yield num;
num = num + 1
}
}
const numbers = naturalNumbers();
console.log(numbers.next().value);
console.log(numbers.next().value);
console.log("...some other work...");
// ... can get another value anytime from the paused generator.
console.log(numbers.next().value);
Copyright ©2024 Educative, Inc. All rights reserved