Generators in JavaScript

In this article, we will understand what Generators are and how we can make use of them in our code.
What are Generators?
It's like a regular javascript function but can return a value more than once and at a defined period of time. Ok, what do you mean?
This comes with a concept called yielding. Just like on the road how cars yield to the other vehicles passing by from time and time again, we can make our functions yield (return) a value as and when required.
Let's understand with a simple snippet:
function* sayHelloManyTimes() {
yield "Hello";
yield "hello";
yield "HELLO";
}
.next()
In order for that to be called, we need to use .next()
what works like the iterators to return the next yield value.
// Let's assign this to a variable `func` so we can easily
// call multiple times.
const func = sayHelloManyTimes();
If you're curious like me, this is what would get printed to the console
when we log func.
So, we can see that it has a prototype of GeneratorFunctionPrototype
.
console.log(func.next());
If you do a .next()
, you will get the first yield value printed with additional details.
{
value: "Hello"
done: false
}
As you can see only one of the yield
values is returned and also notice done: false
that indicates there are some more yields still present. Just like Iterators.
In fact, Generators are used in the background in implementing Iterables. Async/await depends on Generators and Promises in the background.
We can keep doing .next()
until we get done: true
which happens in this case after 4 times.
console.log(func.next());
console.log(func.next());
console.log(func.next());
Just like .next()
, the are other methods like .return()
and .throw()
.return()
.return()
just like a normal function terminates the function at that given state of the yield and returns a value if an argument is provided in the .return(arg)
or simply returns undefined
.
function* sayHelloManyTimes() {
yield "Hello";
yield "hello";
yield "HELLO";
}
const func = sayHelloManyTimes();
console.log(func.next());
console.log(func.return("finish"));
// Prints
// {value: "Hello", done: false}
// {value: "finish", done: true}
// even though there are other yields still pending.
.throw()
.throw()
lets you throw an error from the generator which can be caught using try/catch
.
function* sayHelloManyTimes() {
try {
yield "Hello";
yield "hello";
yield "HELLO";
} catch (err) {
console.log("Error: ", err);
}
}
const func = sayHelloManyTimes();
console.log(func.next());
console.log(func.throw("error"));
// Prints
// {value: "Hello", done: false}
// Error: error
// {value: undefined, done: true}
If you have come down all this far, I hope you liked this article. If yes, please read my other articles on promises, javascript, interview-questions, ...
You can even subscribe to the newsletter to receive the article directly in your inbox.
Cheers
Arunkumar Sri Sailapathi.
Subscribe to my newsletter
Read articles from ArunKumar Sri Sailapathi directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

ArunKumar Sri Sailapathi
ArunKumar Sri Sailapathi
I am a passionate front-end engineer and an aspiring entrepreneur. I like coding and building products from the scratch. I plan to write about some of the interesting things that I came across during my 10+ years of professional career.