Real-life Javascript Generators

How generators in javascript help us write more robust and clean code.

With ES6 we have generators, different kind of functions that may be paused at any time, and resumed later, this allows other code to run during those break periods. Let’s review this small code example to better understand how generators work:

The first two things you notice is the “*” symbol which indicates that declared function is a generator, and “yield” keyword used to pause the function from inside itself, and waits for signal to continue it’s execution.

kindBot.next() // {value: 'Hello, what\'s your name?', done: false}

As you can see when asking our generator to resume it’s execution, we get back an object with value of what was yielded from it and information whether it has finished running.

kindBot.next(‘Ricky’) // {value: 'Hello, Ricky! :)', done: true}

When calling our generator, we can also pass an argument to it, which will replace yield expression.

Benefits of using generators

We quickly reviewed how generators work, but to fully understand the benefits of using them, I will show you a short real-life code example written using: callbacks, promises & generators.

Callbacks

Callbacks helped us enormously in writing asynchronous code using single thread, although after some time spent with javascript we all learned that callbacks stack in form of rotated pyramid, often called callback hell.

As you can see, having just one call to API wouldn’t be so bad, but with every next request we quickly form ugly, not easily maintainable code that calls for trouble..

Promises

In response to callback hell came promises, they flattened our code’s callbacks to mostly one level of indentation, but that’s just a nice by-product.

What’s the most important about promises is that they provided us with ability to return values from asynchronous functions and throwing / catching exceptions, this is really important because that placed them really close to how synchronous functions behave.

Promises definitely are enough to work with asynchronous functions in clean, easily maintainable manner, but we can get even closer to how “simple” our code can look.

Generators

Combined with promises, generators shine among other solutions, they look and feel really gives us sense of writing our functions in “synchronous” way. Just look how beautiful our snippet became after transforming it into generator’s approach:

In most of the cases all we would need to do is remove “yield” with “*” and our code looks exactly like it was working synchronously.

Conclusion

I believe that one of most important characteristics of great code is for it to be easily maintained by other developers and generators give our code exactly that: clean & understandable structure that’s easy to follow & keeps all the good parts of asynchronous programming.