我一直在使用函数作为参数。现在我需要传递一个函数A,它需要函数B生成的参数x。我也可以这样做。通过使用参数调用B中的A。
但我的问题是,我的函数B接受任何类型的函数,并且它不是固定的。它也可能需要函数C,它需要参数y或某些不需要任何参数的函数D.
这可能吗?
function B(done_function){
//some task generate some value
done_function();
}
function B(done_function){
//some task generate some value including args
done_function(args);
}
如何使用参数执行A,C和D函数。
前两个例子不起作用。
答案 0 :(得分:1)
处理此问题的常用方法是忽略它。函数B
根本不关心其他函数如何接受参数。相反,它应仅为其回调提供标准且记录良好的界面:
function B (done_function) {
// do some stuff to generate result
done_function(result);
}
或者,如果函数B
可能异步生成错误,那么它应该done_function(err, result)
。请注意,所有库都这样做。他们不关心你如何写你的功能。
现在,如何将各种类型的函数传递给B
?只需将它们包裹在另一个函数中例如,假设您需要将B
的结果传递给记录器函数,并且需要传递一个指定要记录的文件名的变量。就这样做:
B(function(result) {
logToFile(debugLogFile, result);
});
比如说,您需要修改结果,因为要传递它的函数希望它具有特定格式。做这样的事情:
B(function(result) {
var x = {
some_parameter: something,
result: result
};
doSomethingElse(x);
});
没有函数B
需要知道如何处理它生成的结果的情况。你是程序员,负责在进一步处理之前适当地转换函数B
的结果。
答案 1 :(得分:0)
您可以使用函数a modified version of your CodePen方法:
function B(done_function){
//some task generate some value including args
done_function.call(done_function, args);
}
答案 2 :(得分:0)
让 B 使用单个对象作为参数调用回调,其中包含所有信息:
function B(done_function){
//some task generating some values, including args, for example:
var args = {
status: 3,
code: 'DEC',
location: 'Atlantic',
date: new Date('2017-01-01')
}
done_function(args);
}
使用ES6 destructuring in function parameters,您可以过滤掉所需的信息:
功能 A 可能如下所示:
function A({status}) {
console.log('status is ' + status);
}
B(A);
同样, C 可能如下所示:
function C({code, date}) {
console.log('code is ' + code + ' on ' + date);
}
B(C);
当然,ES6解构只是一个很好的快捷语法,你也可以这样做:
function A(response) {
console.log('status is ' + response.status);
}
B(A);
length
属性如果可以根据为它们定义的参数数量来区分不同类型的回调,那么您可以使用length
属性,如下所示:
function B(done) {
var code = 'DEC';
var status = 1;
var location = 'Atlantic';
var date = new Date('2017-01-01');
switch (done.length) {
case 1:
done(status);
break;
case 2:
done(location, date);
break;
default:
done(code, status, location, date);
}
}
function A(status) {
console.log('status = ' + status);
}
function C(location, date) {
console.log('location = ' + location + ' on ' + date.toDateString());
}
B(A);
B(C);
请注意适用于length
属性值的specific rules。