The Basics of JavaScript Generators

The Basics of JavaScript Generators

JavaScript does a pretty good job of iterating over collections. But what if you don’t know what the collection is, or how big it will be? What if the thing you want to iterate over doesn’t have an iterator to use? JavaScript generators can help!


What Are JavaScript Generators?

JavaScript generators are just ways to make iterators. They use the yield keyword to yield execution control back to the calling function and can then resume execution once the next() function is called again. Once the generator runs out of values to return, it returns a value of undefined, and a done value of true, letting you know that there are no more values. This makes more sense if you can see a simple example.

function* foo() {
  yield 'a';
  yield 'b';
  yield 'c';
}

const foogee = foo();

console.log('getting the first value');
console.log(foogee.next());
console.log('getting the next value');
console.log(foogee.next());
console.log('getting the next value');
console.log(foogee.next());
console.log('getting the next value');
console.log(foogee.next());

The function foo() is a generator function, indicated by the * after the function declaration. The constant foogee instantiates the foo generator function, but simply returns a type of iterator called a Generator. The next() function always returns an object with a value and a done property. The very first time next() is called on the Generator, the function executes the first line which yields execution control back to the caller with a return value of:

{ value: 'a', done: false }

The program logs it to the console. The program then calls next() again, which resumes execution of the generator, yielding a value of:

{ value: 'b', done: false }

The third time, it yields the return object with a value of:

{ value: 'c', done: false }

Now the generator is out of values to yield, so the next time the program calls next(), it returns:

{ value: undefined, done: true }

From this point on, no matter how many more times the program calls next() it will always return that object.


What Would I Use JavaScript Generators For?

You might think, “That’s cool, but I can already iterate over collections in JavaScript. Why would I need to create a JavaScript Generator?”

That’s a fair question. What about things that don’t automatically come in a collection? Like the all-powerful Fibonacci Sequence?

function* fibonacci() {
  let current = 0;
  let next = 1;

  while(true){
    yield current;
    [current, next] = [next, current + next];
  }
}

const gen = fibonacci();
for(let i = 0; i < 10; i++){
  console.log(gen.next().value);
}

This fibonacci generator simply yields the next value in the Fibonacci sequence. There isn’t really a Fibonacci array in JavaScript to iterate over so you need to make your own.


A More Practical Use for JavaScript Generators

While it’s totally cool to nerd out on creating fibonacci generator functions, it’s not super useful for all of you out there writing business software, right? So how about dates? There’s no real way to iterate over all the days in a month or the next thirty days. Create a JavaScript Generator for that!

function* dateGenerator(startDate = new Date()) {
  let currentDate = startDate;
  while (true) {
    yield currentDate;
    currentDate.setDate(currentDate.getDate() + 1);
  }
}

console.log('Next 30 Days');
const dates = dateGenerator();
for(let i = 0; i < 30; i++){
  console.log(dates.next().value.toDateString());
}

This kind of generator can be super useful in everyday business software. Think about creating calendars in a React, Angular, or Vue app. What about saving a reminder to a todo list every day for the next 30 days?

Normally, you’d have to create an array of these values by looping over the line that sets the date.

currentDate.setDate(currentDate.getDate() + 1);

Once you had the size of array you want, it would loop over that array to get the value you want. This is particularly useful for those kinds of things that don’t readily have a collection that you can iterate over.

What uses can you think of for generators?


Learn More JavaScript Goodness!

Introducing TensorFlow.js: Machine Learning in Javascript

Full Stack Developers: Everything You Need to Know

ES5 to ESNext — here’s every feature added to JavaScript since 2015

5 Javascript (ES6+) features that you should be using in 2019

The Complete JavaScript Course 2019: Build Real Projects!

JavaScript: Understanding the Weird Parts

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

The Full JavaScript & ES6 Tutorial - (including ES7 & React)

Originally published by Lee Brandt at https://developer.okta.com