Is there an elegant way to asynchronously map an object or array in coffeescript? (Or javascript.)
Imagine I have some things in an object:
things =
x:
...
y:
...
z:
...
thingCount = 3
I want to create a method that will process each of these things and return the processed object. The process has to make an asynchronous call to fetch some info about each thing.
At first I tried just to loop through the properties like so:
processThings = (callback) ->
processedThings = {}
count = 0
for key,val in things
asyncJob key,val (err,result) ->
if err
callback error
else
# PROBLEM: key has the incorrect value here
processedThings[key] = result
count += 1
if count == thingCount
callback null,processedThings
The problem is that the value of key changes in the loop. So my solution is to create a sub-function so that the key variable is contained within its closure:
processThings = (callback) ->
processedThings = {}
count = 0
processThing = (key,val) ->
asyncJob key,val (err,result) ->
if err
callback error
else
processedThings[key] = result
count += 1
if count == thingCount
callback null,processedThings
processThing key,val for key,val of things
But boy howdy that sure is fugly. Is there a preferred pattern for this?
CoffeeScript covers this with the
dokeyword, described at the end of Loops and Comprehensions:It can be applied to your code as: