Experts Blog

The Miracle of Generators

"But can't we just use async/await?" In short. Yes. But don't you want to know what is going on behind the scenes?

This was the only question that followed an hour-long, mind-bending talk from Bodil Stokke where she explained and demonstrated the power of ES2016's iterator and generator features.

I'll admit it, this talk was a little out-dated. ES2016 is already more than 1 year old, and ES2017 was released a couple of months ago. But the ability to write asynchronous Javascript is so awesome that its no wonder we are still talking about it more than 1 year later.

For the non-developers, asynchronous code is when you delay the execution of a program until a different part of it is complete. An example could be when you want to wait for a response from the server or for a complex calculation to be completed. The key word here is "wait." Before ES2016, the most common way to simulate "waiting" was with callback functions, which eventually led to "callback hell." Believe me, it is as bad as it sounds.

With ES2016 we got promises, yield, iterators and generators and with ES2017, async/await. All ways that build asynchronicity into the Javascript core, without callbacks. In my experience, promises are the most widely used asynchronous feature, followed by async/await. In fact, before watching this presentation, I had never written an iterator/generator, nor had I seen one in the wild.

I'm sorry for the code, but I feel i would be doing an injustice to the presentation (which was one hour of playing with the command line) if I didn't.

With promises, you can do this...
return getItems()
  .then((items) => /* do something with the items */)
  .catch((err) => /* do some error handling */)

That is pretty good. the getItems function will return a promise that, when resolved, will trigger then or when rejected will trigger catch. But the functions passed to then and catch look very similar to a callback.

With Generators, we can take it one step further and wait for multiple promises to resolve sequentially with the yield keyword...
let generator = function* () {
  let items = yield getItems(); // pauses until getItems() returns    
  let item = yield filterItems(id, items.value); // pauses until filterItems() returns
};

let iterator = generator();

iterator.next(); // { value: {items}, done: false }
iterator.next(); // { value: {item}, done: false }
iterator.next(); // { value: undefined, done: true }

/* the sequential next calls above can be programatically abstracted, but thats too much for this blog. And that is almost exactly what async/await does. */

With async/await...
async function getItemById(id) {
  let items = yield getItems(); // execution will pause until getItems returns
  let item = yield filterItems(id, items); // execution pauses until filterItems returns
  return item;
};

// strikingly similar to the generator above...

Before this presentation, I had never written a generator function. And I may never have to.

With the frontend ecosystem evolving at break-neck pace, it is difficult to keep up with every development, much less understand the inner workings of all new features. However, these asynchronous features are game-changing, and a deeper understand of them is essential to writing elegant javascript.

In summary, new features officially added to Javascript in the last 14 months have made writing asynchronous programs much easier. With more and more business logic being implemented in the frontend, this will make handing complex tasks easier. But learning how to use these new features is not enough. We should strive to learn how they work as well.

Connecting Frontend and Backend with Contract Driven Development

While the concepts and ideas around headless CMS and its use cases are getting more wide spread, our Sitecore team started the journey on this topic by introducing Sitecore Javascript Services JSS for the multisite platform for Zurich Airport. Tobias Studer has explored the uncharted territory step by step and gives an insight into the considerations and challenges that shaped the final solution.

Our Responsibility for Sustainable Digital Services

It is high time we take a closer look at the environmental footprint of digital services. This is not a new issue, but one that is becoming more relevant in the current situation as the COVID-19 pandemic has led to an explosion of data traffic volumes.