Asynchronous calls with ES6 generators

ES6 generators have landed in Chrome 39 Beta on 9th of October and are already available in the stable version.
This means that brand new development practices are already applicable, although for supporting older browsers you might need to fallback to the traceroute compiler.

A cool module, which TJ developed, called co, is available for quite a while (his initial commit in the co repository was on 6th of June 2013).

A few months ago Jake Archibald wrote an article about the awesomeness of the async functions in ES7 and how we can “emulate” them using ES6’s generators, using his spawn function, which has subset of the features of co.

In this blog post we’ll take a look at standard ways of handling asynchronous calls and how we can improve the readability of our code using generators. We’ll also take a further look at the implementation of spawn, since there are few tricky moments there.

This looks…alright, I guess.
What we do is to fetch the users.json and later, in the success callback, fetch each user in the users_list array. Excluding the ugliness of the code (plenty of nested callbacks), the functionality is not that bad because we can fetch up-to 6 users simultaneously (that’s the limit in Chrome).

I believe, the code looks a little bit more compact. We still fetch up-to 6 users simultaneously, because of the call data.users_list.map(getJSON).

Solution with generators

Since async functions are still not implemented in the modern browsers, as Jake suggests, we can use generators as something akin to them. Let’s leave our getJSON implementation untouched and implement loadUsers using a generator:

This snippet will invoke getJSON and will receive the returned promise (as generator.next().value). On resolve of the promise, the callback will be invoked with JavaScript object, equals to the parsed JSON we just fetched from users.json.

As next step we need to invoke the generator with the received object, this way the local variable users (inside loadUsers) will hold the correct value and we will have access to the users_list property, over which we need to iterate with map:

Once we invoke the generator with the users object we continue the execution of the generator and enter the loop (for...of) where we invoke yield with the first promise. Once the promise is resolved we enter the then callback and we can request the second user: