Reputation: 3486
I've a small problem with a function in a class of my nodejs/express server.
I have the following function :
@resolveServers = (url, servers, resolved) ->
result = []
treatServer(url, server, (serverObject) ->
result.push serverObject
resolved result if result.length is servers.length
) for server in servers
And since the treat server function can take a wild, and as hinted on this question of mine, I was considering using async each for this.
So I'm here :
@resolveServers = (url, servers, resolved) ->
result = []
async.each(servers, treatServer(url, server, (serverObject) ->
result.push serverObject
resolved result if result.length is servers.length
), (err) ->
if err
console.log next err
)
And I currently get the following error :
ReferenceError: server is not defined
The treatServer function needs the url and a server for the servers array. But I don't know how to get this server instance for each one of them, and pass it to the treatServer function.
Any idea on what I'm doing wrong ?
Thanks already.
Update: I'm slightly disappointed as I have no gain at all using async. The function I used takes approximatively 6500ms and the async one is the same. I guess the each function from coffeescript does its job really well.
Update: After further tests, I'm finding out that the function is slower with async. Really wierd.
Upvotes: 0
Views: 1511
Reputation: 203419
I think you want async.map
instead: it gathers the results of all operations and passes them as an array to the final callback. It also maintains the order of the input array, which async.each
doesn't (but that might not be an issue).
@resolveServers = (url, servers, resolved) ->
async.map(servers, (server, callback) ->
treatServer(url, server, (serverObject) ->
callback null, serverObject
)
, (err, result) ->
if err
console.log next err
resolved err, result // see text
)
Since my CF isn't that great, a JS version too:
function resolveServers(url, servers, resolved) {
async.map(servers, function(server, callback) {
treatServer(url, server, function(serverObject) {
callback(null, serverObject);
});
}, function(err, result) {
if (err)
console.log(err);
resolved(err, result);
});
}
I would also suggest following the common Node idiom for asynchronous callbacks, where the first argument is an error object (or null
is no errors occurred), and the second argument the result value. That way, you can propagate your errors all the way back the calling chain.
Upvotes: 4
Reputation: 31580
The iterator function of async.each takes two parameters like this:
async.each(openFiles,
function(file, callback) {
// do something with file
callback()
}, function(err){
// if any of the saves produced an error, err would equal that error
});
in your case you get a server and a callback, so I would rewrite to something like this:
@resolveServers = (url, servers, resolved) ->
result = []
async.each(servers, (server, callback) ->
treatServer(url, server, (serverObject) ->
result.push serverObject
resolved result if result.length is servers.length
callback()
)
, (err) ->
if err
console.log next err
)
Upvotes: 2