使用async.waterfall减少嵌套但增加了混乱

wtj*_*nes 6 node.js node-async

我试图通过使用减少异步调用(node + socket.io)的嵌套,async.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);
      });
    });
  });
Run Code Online (Sandbox Code Playgroud)

// 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);
      });
    }
  ]);
Run Code Online (Sandbox Code Playgroud)

目标是可读性,但我发现冗余的参数传递增加了混乱.我知道我可以在调用async.waterfall之前声明变量并根据需要存储params以便以后在链中使用但这对可读性没有帮助.

有没有办法让这更优雅?

Mic*_*ley 5

我对瀑布中设置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);
  });
}
Run Code Online (Sandbox Code Playgroud)

这具有将任何error参数传递到最终回调的额外好处,因此您可以根据需要处理它们(例如clientFn,使用指定错误的参数调用).