Maybe you have heard about this feature in ES6 or you just didn’t have time to play with it.
It is something, that I have learned a few days ago and it's super cool.
Let me explain it to you in a few steps.
So Generators looks like a normal function, but it allows us to pause the execution of the function and continue it later.
So below you can see an example of the generator and we will break it down to see how it works:
function* avengersGenerator() { // Declaring the generator
yield "Hulk"; // Pausing the execution
yield "Thor";
yield "Iron man";
return "Ultron"; // Example of finishing the generator
yield "Spiderman";
}
const iterator = avengersGenerator(); // Creating iterator
iterator.next(); // Iterating on the generator
Declaring the generator
Generators look similar to a normal function, the only difference is we have to define an *
(asterisk) after the word function.
function* avengersGenerator() {
...
}
Yield it!
We can yield
the function, which basically would stop the execution of the function when it gets to the first yield
.
function* avengersGenerator() {
yield "Hulk" // The execution would pause here.
yield "Iron man" // When we resume we would start here.
}
Creating the iterator
On iterator, we can call. So by this, we will prepare our generator for action.
const iterator = avengersGenerator();
Next method
This enables us to continue the execution of the function. Also, this method provides us with the object with the yielded value and whether the generator has yielded its last value, as a boolean.
iterator.next(); // [1] Object {value: "Hulk", done: false}
iterator.next(); // [2] Object {value: "Thor", done: false}
iterator.next(); // [3] Object {value: "Iron man", done: false}
iterator.next(); // [4] Object {value: undefined, done: true}
Return / Exiting
Once a return is being called, it would finish the generator. It basically sets the done
property to true
.
function* avengersGenerator() {
yield "Hulk";
return "Ultron"; // Example of finishing the generator
yield "Thor"; // Sad Thor and Spiderman wouldn't be called
yield "Spiderman";
}
iterator.next(); // [1] Object {value: "Hulk", done: false}
iterator.next(); // [2] Object {value: "Ultron", done: true}
In my opinion, generators are quite a cool thing to play with or at least to know what it does.
In the next post, I will explain, how generators helped me to solve one case at my work thanks to the possibility to cancel the promise when needed with generators in ES6.
UPDATE 1: I finally got some time to write another blogpost about generators, so here it goes 👉 Canceling promises with generators in ES6 Javascript
Thanks for reading
Let me know in the comments section how you feel about this generators series. If you love it, you know what to do! Share it with your friends and colleagues.
If you want me to cover some topics in the next post, DM me on here on dev.to or on twitter @phung_cz, or if you have any suggestions, feel free to comment below.
See ya next time and keep on hacking ✌
Top comments (27)
I understand how they work, but I still have no idea where to use a generator.
I will write another post with examples where generators come in handy
Seems people agree. Unrelated: I also hate that you can't restart a generator. Despite the initial spec saying you could.
I finally got some time, so I wrote down one example for the usage of generators, hope that you'll enjoy reading it 👉dev.to/phung_cz/canceling-promises...
The only scenario I can think of is using an asynchronous generator in combination with the "for await ... of" loop (developer.mozilla.org/en-US/docs/W...) when not using libraries such as rxjs.
Interesting! I didnt know about for await of and I thought I had mastered async await :/
redux-sagas used a lot of generator functions
i did a very simple example:
I finally got some time, so I wrote down one example for the usage of generators, hope that you'll enjoy reading it 👉dev.to/phung_cz/canceling-promises...
You have an error in your return example: the value you
return
will be returned by the iterator'snext
call as a single{value: "Ultron", done: true}
, not in two distinct steps.Also,
undefined
should be between quotes, it's not a string but a specific value.Nice catch, just fixed that, thanks ;)
I didn't know about generators! interesting!
I hope that you will try them out!
I will research them and probably will try to use them!
And I'll wait for the next article you mentioned in this one ;)
I finally got some time, so I wrote down one example for the usage of generators, hope that you'll enjoy reading it 👉dev.to/phung_cz/canceling-promises...
I just read it and it was nice but to be honest, I still have trouble grasping how it could be more beneficial than other methods.
It's Monday and I haven't played with it so I'll revisit your article later and it will probably make more sense to me :)
Typo in code snippet:
yeild "Spider man";
Fixed, thanks!
Loved the article! I was wondering if we can use more combinations in the
yield
part . I don't know, maybe callbacks? Is it possible?I have not tested it yet 😓
yes, we can! You need to any function there ;)
Looking forward to your next post. What you have shown so far can be achieved much more easily with a simple array but I am sure there are better use cases for generators. I guess it gets more interesting when you don't know in advance how many values need to be generated.
I finally got some time, so I wrote down one example for the usage of generators, hope that you'll enjoy reading it 👉dev.to/phung_cz/canceling-promises...
Thanks guy for sharing. Hope you write an article, how to apply generator for real usecases. Thanks again! And we can keep contact because I see your Vietnamese name :D
Hey, haha sure, feel free to follow me on dev.to :D
I finally got some time, so I wrote down one example for the usage of generators, hope that you'll enjoy reading it 👉dev.to/phung_cz/canceling-promises...
Nice post, but I am wondering where to apply generators in real world.
What I got is that async / await syntax «abstracts» this stuff or it is not the case?
Yep, will write about it in my next post ;)