我正在尝试通过使用 async.waterfall
来减少异步调用 (node + socket.io) 的嵌套最后我不得不在 waterfall 中附加参数,因为稍后需要它们。这段代码可能解释得更好:
//原版:
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 版本
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);
});
}
]);
目标是可读性,但我发现多余的参数传递增加了困惑。我知道我可以在调用 async.waterfall 之前声明变量,并根据需要存储参数供以后在链中使用,但这无助于提高可读性。
有没有办法让它更优雅?
最佳答案
我很好奇您的 waterfall 流中设置 turn action
处理程序的第一个函数。因为它只是指定一个事件处理程序,所以它在技术上是同步的(即使处理程序本身将被异步调用)。我可能会这样重构它:
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);
});
}
这具有将任何 error
参数传递到最终回调中的额外好处,因此您可以根据需要处理它们(例如,使用指定错误的参数调用 clientFn
) .
关于node.js - 使用 async.waterfall 减少嵌套但增加了困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12239982/