Resolving JavaScript Objects Containing Promises
Dealing with multiple asynchronous calls makes JavaScript promises outshine the classic callback pattern.
Unlike callbacks, you can wait for multiple promises to complete before proceeding.
For example, in the Q framework, you can use the Q.all()
function to wait for multiple promises to complete.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Now, this works well for an array, but as promise dependencies increase, it may be useful to reference these values more descriptively than an array index. Usually, you’d want to wrap dependencies in an object like this:
1 2 3 4 5 |
|
Now, Q doesn’t have a way to await the promises inside this object.
If you just pass it to Q.all()
it will finish before the promises are resolved, because the “dependencies” variable is an object, not a promise.
However, there is a pretty simple workaround using Lo-Dash (or Underscore):
1 2 3 4 5 6 7 8 9 10 |
|
Basically we’re unzipping the keys and values from the “dependencies” object, then rezipping them with the _.zipObject()
function when the promises are resolved.
Note that you can safely mix promises and non-promises. For example:
1 2 3 4 5 |
|
Also note that this only works on a “flat” object. Any nested objects won’t be resolved. It wouldn’t be terribly difficult to write a utility function for recursively traversing an object and awaiting its promises, but I’ll leave that as an exercise for the reader.