Javascript 如何避免这种情况;“最终回调”;图案
假设我有以下代码:Javascript 如何避免这种情况;“最终回调”;图案,javascript,node.js,callback,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 {
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 );
var baz=函数(arg){
对于(变量i=0;i
在本例中,我说我正在注入baz
行为,而不是console.log
行为
在本文中,我使用这个模式来注入我想要的行为。例如,注入将某些记录打印到控制台的行为,而其他一些文件db.js
(尚未编写)可能注入将这些记录添加到数据库的行为,等等
我不确定这是否是实现我想要的最好方式。有更好的方法吗?您暗示将执行一些异步任务,因此让我们模拟一个异步任务:
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正确指出的那样,函数修改传递给它的值不是一件好事。这是函数的“副作用”,如果您不能期望值在整个执行过程中保持一致,那么调试将非常困难。因此,您应该为下一个继续调用创建一个新值。而不是修改<代码> ARG并通过<代码> ARG周围,您应该考虑<代码> ARG > <强>不可更改< /强> .< /P>我不明白您在问什么。函数不返回任何值。因此,我假设你只使用它们的副作用。
foo
函数根本不使用其continuation
参数。函数中的递归可以转换为迭代循环。更好的是,只需在bar
中设置if(arg>2)arg=2
,在foo
中设置if(arg>1)arg=1
。你根本不需要循环。我不知道你说的注射行为是什么意思。说到这里,你需要清楚地说明你的问题。也许这是一个.Mh,也许我的降价不够清楚。我用arg--
来代替“使用arg做一些工作”。例如,考虑提交带有{page:arg}
@AaditMShah的分页API请求。也许这更有意义?我认为您正在寻找bar(3,函数(x){foo(x,console.log);})代码>。不要将continuation
传递给continuation
,并删除多余的行为
参数。