But you should read this anyway…
As the async/await syntax continues to grow in popularity, so does curiosity about their inner workings. It’s easy enough to piece together through a google search that the underpinnings of async/await is a combination of Promises(ok, sure I know Promises) and Generators(huh?).
The purpose of this article is as follows:
- explore basic Generator functionality
- talk about how Generators + Promises = async/await
- make the argument that you don’t need to worry about learning Generators
- this article assumes some basic knowledge of Promises
Iterators and Generators — but mostly Generators
Starting with ES6, there have been several new functions added to the language that aim to make dealing with asynchronous data streams and collections of objects easier. Iterators and Generators fall in this category.
Iterators are powerful in that they provide a means to access items in a collection one at a time, while keeping track of the current index.
Above we pass in a simple array with 2 values and we iterate over the values by calling it.next(). Note the full commented responses.
Now for Generators. Generators are functions that serve as a factory for Iterators. Let’s look at a basic example, then we will discuss the 2 basic parts of a Generator, the Generator Function and the Generator Iterator.
Note the syntax, the asterisk indicates that the function is a generator and the yield keyword which pauses function execution( 😮) and returns(yields) a value.
Earlier I mentioned the 2 parts of a Generator:
- Generator Function — defined with an asterisk near the function name or keyword
- Generator Iterator — created when you invoke the Generator Function
So here we see the Generator Factory at work, Generating Iterators.
At this point, things begin to get more interesting. Communication with Generators can happen in both directions, Generators can yield values to Iterators, but Iterators can also send values to Generators in the
Generators + Promises
Now we can talk for a moment about how Generators and Promises form the foundation for the async/await expression. Imagine for a moment that instead of yielding values the Generator yielded Promise functions. You could then wrap the generator in a function that could wait for the Promise to resolve and return the Promise value to the Generator in the .next() method as we just demonstrated. There is a popular library called coroutines that does just that. Really simply, something like this:
Do I need it?
My opinion of Generators is that you need them in order for async/await to work, but you don’t need to learn to incorporate them directly into your code. Generators introduce to JS the ability to pause function execution and return to it when(if) we see fit. Up until now we expected functions to run to their completion upon execution. This is a revelation, but one that async/await neatly wraps up for us.
Some of the counter arguments are that bundled code devolves async/await into generators so, being familiar with Generators may help you in the debug process. I view that differently though that trying to find ways to incorporate Generators into your code directly.
That’s all for this round. We covered Iterator and Generator basics, how Generators + Promises got us to async/await and why you should not try and force Generators into your JS repertoire.
What are your thoughts on Generators? Is there a use case that I am not thinking of? Let me know your thoughts and questions and give me a follow on twitter. Keep after it.
Further Reading that I found helpful:
IntroductionHave you ever needed to loop through a list, but the operation took a significant amount of time to…code.tutsplus.com