我如何避免这种情况"最终的回调"图案?

时间:2015-04-10 09:23:22

标签: javascript node.js callback

我们说我有以下代码:

var foo = function( arg, continuation, behavior ) {
  if ( arg > 1 ) {
    // Do some work with arg, for example send a paged API request.
    console.log("foo: " + arg--);

    continuation( arg, continuation, behavior );
  } else {
    behavior( arg );
  }
},

bar = function( arg, continuation, behavior ) {
  if ( arg > 2 ) {
    // Do some other work with arg.
    console.log("bar: " + arg--);

    bar( arg, continuation, behavior );
  } else {
    continuation( arg, continuation, behavior );
  }
};

bar( 3, foo, console.log );

我的想法是,我想在bar的调用中指定哪个函数最终将成为foo的回调,这将在稍后的调用图中被调用。

例如,我可能不希望console.log arg的最终值,而是将其用作重复某条消息的次数:

var baz = function( arg ) {
  for (var i = 0; i < arg; i++) {
    console.log("baz");
  }
};

bar( 4, foo, baz );

在这种情况下,我说我注入 baz行为而不是console.log行为。

some code I wrote我使用此模式注入我想要的行为。例如,cli.js注入了将一些记录打印到控制台的行为,而其他一些文件db.js(尚未编写)可能会注入将这些记录添加到数据库的行为,依此类推。 / p>

我不确定这是否是实现我想要的最佳方式。有没有更好的方法呢?

1 个答案:

答案 0 :(得分:1)

你暗示你会做一些异步任务,所以让我们模拟一个异步任务:

function mockApiRequest(mockResponse, callback) {
  setTimeout(function() { callback(mockResponse) }, 500);
}

现在让我们修改你的代码以使用我们的api请求:

function sendPages(pageNumber, continuation, behavior) {
  if ( pageNumber > 1 ) {
    behavior('Uploading ' + pageNumber);
    mockApiRequest({success:true}, function(apiResponse) {
      if (apiResponse.success) {
        behavior('Successfully uploaded ' + pageNumber);
        continuation(pageNumber-1, continuation, behavior);
      }
      else {
        behavior('Failed to upload ' + pageNumber);
      }
    });
  } else {
    behavior('Unsure what to do with ' + pageNumber);
  }
}

正如Aadit所说,你的函数修改传递给它的值并不是一件好事。这是一种副作用&#34;如果你不能期望整个执行过程中的值是相同的,那么函数会很难调试。因此,您应该为下一个继续调用创建一个新值。您应该考虑将arg视为不可变,而不是原地修改arg并传递arg