At the moment Node.js is my web development language of choice, but occasionally I come across something that really grinds my gears. I sometimes find that I’ve fallen into an async hell that screws up a lot of things. For example, maybe I’ve designed an API endpoint that makes a few requests to external services. Before returning data to the client (user), manipulations must be done on the external service data requested. How do we do all this?
Let’s take a look how we would cover these scenarios.
Before I go forward, I must say this may not be the best solution, but it is most certainly a solution. If you’ve got a better solution, please post it in the comments.
The data in this example doesn’t really matter, but let’s assume we have a JSON array called jsonArray
that looks like the following:
[
{
firstname: "Nic",
lastname: "Raboy"
},
{
firstname: "Maria",
lastname: "Raboy"
},
{
firstname: "Arianna",
lastname: "Raboy"
}
]
Now let’s assume our goal here is that we want to transform this JSON data, one object at a time, using some asynchronous function. We want to return the transformed data back to the client application that called this function and that might look like the following:
var transformation = [];
var counter = 0;
for(var i = 0; i < jsonArray.length; i++) {
Awesomify.transform(jsonArray[i], function(error, result) {
transformation.push(result);
if(counter == jsonArray.length - 1) {
res.send(transformation);
}
counter++;
})
}
Here we’re assuming that Awesomify.transform
is real and that it is an async function. Like mentioned earlier we can’t just call res.send
after the loop ends because the transformations may not have finished. Instead in the above code we’re waiting until the last asynchronous function call finishes.
This simulated wait is accomplished by keeping a counter that only increases when the async function finishes. Doesn’t matter if it errors out or succeeds. When this counter matches the array length we know that we’re finally done with the transformations and we can quit. By quit, I mean return the transformed array back to the user.
Maybe not the best way to do things, but keeping a counter on a per asynchronous function basis allows us to loop through a bunch of async functions and return only when everything is complete. If you’ve got a better way to handle this scenario, post your method in the comments.