Get started with 33% off your first certification using code: 33OFFNEW

How to use Generators in JavaScript

2 min read
Published on 31st October 2023

JavaScript, a language that has been consistently evolving, introduced a powerful feature in its ES6 (ECMAScript 2015) iteration: Generators. While they might seem daunting at first, generators are invaluable tools for handling asynchronous operations and creating custom iterable sequences. Let's unwrap the mystique behind JavaScript generators.

What Are Generators?

Generators are special functions in JavaScript that allow you to yield (or produce) multiple values on a per-request basis. They pause their execution when yielding a value and can resume from where they left off. This "pausing" capability makes generators versatile for many scenarios, particularly asynchronous tasks.

Basic Syntax of Generators

Generators are defined similarly to regular functions but with an asterisk (*). The yield keyword is used to produce a sequence of values.

function* myGenerator() {
  yield 'first value';
  yield 'second value';
  yield 'third value';

Using a Generator

To use a generator, you must first call it, which returns a generator object:

const gen = myGenerator();

This object follows the iterator protocol and has a next() method:

console.log(; // { value: 'first value', done: false }
console.log(; // { value: 'second value', done: false }
console.log(; // { value: 'third value', done: false }
console.log(; // { value: undefined, done: true }

Benefits of Generators

  1. Unlike traditional functions that might build and return a huge array, generators produce values on the fly. This means you're not storing large data structures in memory.

  2. Together with Promises, generators offer a smoother way to handle asynchronous operations. This synergy gave birth to async/await, which is essentially syntactic sugar over generators and promises.

  3. Beyond producing a sequence of values, generators can be used to define custom iteration behaviors.

Yielding Other Generators

Generators can yield other generators, making them composable:

function* generatorA() {
  yield 'A1';
  yield 'A2';

function* generatorB() {
  yield* generatorA();
  yield 'B1';

const genB = generatorB();
console.log(; // { value: 'A1', done: false }

Generators and Error Handling

You can handle errors in generators with try-catch blocks. If an error is thrown inside a generator, it will set the done property of the generator to true.

function* errorGenerator() {
  try {
    yield 'all good';
    throw new Error('Problem occurred');
  } catch (err) {
    yield err.message;

Real-world Use Cases

  1. Fetching chunks of data lazily, such as paginated API results or reading large files in segments.

  2. Generating infinite sequences, like an endless series of unique IDs.

  3. Pausing and resuming functions, allowing for more complex flow control.

Generators offer an alternative and often cleaner approach to handling asynchronous operations and generating sequences in JavaScript. While they've been somewhat overshadowed by the rise of async/await, understanding generators gives a deeper insight into the language's capabilities. With generators in your JS toolkit, you're better equipped to tackle a wider range of programming challenges.