一个函数(需要参数)作为另一个函数的参数

时间:2017-04-05 08:05:52

标签: javascript function

我一直在使用函数作为参数。现在我需要传递一个函数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函数。

前两个例子不起作用。

3 个答案:

答案 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); 
}

call

答案 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