I am trying to reduce the nesting of async calls (node + socket.io) by using async.waterfall
and I ended up having to append parameters down the waterfall because they are needed later. This code might explain better:
// Original version:
socket event: turn action
socket.on('turn action', function(gameId, turnAction, clientFn) {
socket.get('corp', function(err, corp) {
gameProvider.processTurnAction(gameId, corp.id, turnAction, function(err, msg, game) {
clientFn(msg, game);
});
});
});
// async.js version
async.waterfall([
function(callback) {
socket.on('turn action', function(gameId, turnAction, clientFn) {
callback(null, gameId, turnAction, clientFn);
});
},
function(gameId, turnAction, clientFn, callback) {
socket.get('corp', function(err, corp) {
callback(null, gameId, turnAction, clientFn, corp);
});
},
function(gameId, turnAction, clientFn, corp, callback) {
gameProvider.processTurnAction(gameId, corp.id, turnAction, function(err, msg, game) {
clientFn(msg,game);
});
}
]);
The goal was readability but I find the redundant param passing adds clutter. I know that I can declare variables before the call to async.waterfall and store the params as needed for later use in the chain but that doesn't help with readability.
Is there a way to make this more elegant?
I'm curious about the first function in your waterfall that sets up the turn action
handler. Since it just specifies an event handler, it's technically synchronous (even though the handler itself will be called asynchronously). I'd probably refactor it thusly:
socket.on('turn action', function(gameId, turnAction, clientFn) {
async.waterfall([
function(callback) { socket.get('corp', callback); },
function(corp, callback) {
gameProvider.processTurnAction(gameId, corp.id, turnAction, callback);
}
], function(err, msg, game) {
// err will be set if either of the two `callback`s were called with
// an error as the first parameter
clientFn(msg, game);
});
}
This has the added benefit of passing any error
parameters into the final callback, so you can handle them as necessary (e.g. call clientFn
with a parameter specifying an error).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With