JavaScript:将参数传递给回调函数


289

我正在尝试将一些参数传递给用作回调的函数,该怎么做?

function tryMe (param1, param2) {
    alert (param1 + " and " + param2);
}

function callbackTester (callback, param1, param2) {
    callback (param1, param2);
}

callbackTester (tryMe, "hello", "goodbye");

9
您正在做的事情应该起作用。你有什么问题?
丹尼尔·瓦萨洛

1
您的代码工作正常,这是什么问题?
Sarfraz 2010年

1
它应该工作... jsfiddle.net/QXQZj
斯托伊奇

抱歉,这是我的主要代码语法错误,我想是因为这是我第一次在JavaScript中使用回调
vitto 2010年

如果您想向回调添加参数但不能更改调用的内容(因为您无权更改参数顺序,则可以将某些回调参数与JS绑定预先绑定,如我所展示的这个答案:stackoverflow.com/a/28120741/1695680
ThorSummoner 2015年

Answers:


253

如果您想要更一般的东西,可以使用arguments变量,如下所示:

function tryMe (param1, param2) {
    alert(param1 + " and " + param2);
}

function callbackTester (callback) {
    callback (arguments[1], arguments[2]);
}

callbackTester (tryMe, "hello", "goodbye");

但是否则,您的示例可以正常工作(可以在测试器中使用arguments [0]代替回调)


53
只要我们本着宽泛的精神,它callback.apply(arguments)的功能主体就callbackTester可以扩展到两个论点之外。
史蒂文

1
抱歉,这是主代码中的语法错误,我想是因为这是我第一次在JavaScript中使用回调,您已经帮助我了解它不是探针,并看到了一个很好的例子。
vitto 2010年

3
仅供参考,使用匿名函数(Marimuthu的答案)或.bind()(Andy的答案)是将参数传递给回调的更简洁的方法。
antoine

203

这也将起作用:

// callback function
function tryMe (param1, param2) { 
    alert (param1 + " and " + param2); 
} 

// callback executer 
function callbackTester (callback) { 
    callback(); 
} 

// test function
callbackTester (function() {
    tryMe("hello", "goodbye"); 
}); 

另一种情况:

// callback function
function tryMe (param1, param2, param3) { 
    alert (param1 + " and " + param2 + " " + param3); 
} 

// callback executer 
function callbackTester (callback) { 
//this is the more obivous scenario as we use callback function
//only when we have some missing value
//get this data from ajax or compute
var extraParam = "this data was missing" ;

//call the callback when we have the data
    callback(extraParam); 
} 

// test function
callbackTester (function(k) {
    tryMe("hello", "goodbye", k); 
}); 

2
这很有用,因为它还允许匿名函数像这样传递参数:callbackTester(function(data){tryMe(data,“ hello”,“ goodbye”);});
Michael Khalili 2014年

我还想检查回调实际上是否是一个函数。if (typeof window[callback] == 'function') window[callback].call(this);
GreeKatrina 2015年

63

您的问题不清楚。如果您询问如何以更简单的方式执行此操作,则应查看ECMAScript第五版方法.bind(),它是Function.prototype的成员。使用它,您可以执行以下操作:

function tryMe (param1, param2) {
    alert (param1 + " and " + param2);
}

function callbackTester (callback) {
    callback();
}

callbackTester(tryMe.bind(null, "hello", "goodbye"));

您还可以使用以下代码,如果当前浏览器中不提供该方法,则会添加该方法:

// From Prototype.js
if (!Function.prototype.bind) { // check if native implementation available
  Function.prototype.bind = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments),
        object = args.shift(); 
    return function(){ 
      return fn.apply(object, 
        args.concat(Array.prototype.slice.call(arguments))); 
    }; 
  };
}

bind() -PrototypeJS文档


出于兴趣,Array.prototype.slice.call(arguments)和之间有什么区别arguments.slice()
sje397

7
@ sje397:参数不是* real *数组,因此它没有slice()方法。但是,Array.prototype上的slice()方法是有意通用的,因此您可以传递具有数字索引和length属性的任何对象,并且它将起作用。
安迪E

2
这是最优雅的答案
antoine 2015年

这个.bind()确实很棒,并且扩展了回调的使用和简单性。作为了解它的基本示例,如果您有:f = function(arg1,arg2){alert(arg1+arg2);}.bind(this,"abc"); f("def") // Gives "abcdef"
Le Droid

这确实是一个好答案。太棒了,对我来说很好。谢谢您:)
Vishnu Mishra'8

13

当您有一个回调,该回调将由代码以外的其他东西调用并带有特定数量的参数,并且您希望传递其他参数时,可以传递包装函数作为回调,并在包装​​内部传递附加的参数。

function login(accessedViaPopup) {
    //pass FB.login a call back function wrapper that will accept the
    //response param and then call my "real" callback with the additional param
    FB.login(function(response){
        fb_login_callback(response,accessedViaPopup);
    });
}

//handles respone from fb login call
function fb_login_callback(response, accessedViaPopup) {
    //do stuff
}

9

如果不确定要将多少参数传递给回调函数,请使用applyfunction。

function tryMe (param1, param2) {
  alert (param1 + " and " + param2);
}

function callbackTester(callback,params){
    callback.apply(this,params);
}

callbackTester(tryMe,['hello','goodbye']);

4

在函数包装器中将“子”函数作为参数传递/与参数一起传递,以防止在调用“父”函数时对它们进行评估。

function outcome(){
    return false;
}

function process(callbackSuccess, callbackFailure){
    if ( outcome() )
        callbackSuccess();
    else
        callbackFailure();
}

process(function(){alert("OKAY");},function(){alert("OOPS");})

4

来自具有任意数量的参数和回调上下文的问题的代码:

function SomeFunction(name) {
    this.name = name;
}
function tryMe(param1, param2) {
    console.log(this.name + ":  " + param1 + " and " + param2);
}
function tryMeMore(param1, param2, param3) {
    console.log(this.name + ": " + param1 + " and " + param2 + " and even " + param3);
}
function callbackTester(callback, callbackContext) {
    callback.apply(callbackContext, Array.prototype.splice.call(arguments, 2));
}
callbackTester(tryMe, new SomeFunction("context1"), "hello", "goodbye");
callbackTester(tryMeMore, new SomeFunction("context2"), "hello", "goodbye", "hasta la vista");

// context1: hello and goodbye
// context2: hello and goodbye and even hasta la vista

2

在此简单示例中使用咖喱函数。

const BTN = document.querySelector('button')
const RES = document.querySelector('p')

const changeText = newText => () => {
  RES.textContent = newText
}

BTN.addEventListener('click', changeText('Clicked!'))
<button>ClickMe</button>
<p>Not clicked<p>


0

一种新版本的方案,在该方案中,回调将由其他函数(而不是您自己的代码)调用,并且您想添加其他参数。

例如,让我们假设您有很多嵌套调用,包含成功和错误回调。在此示例中,我将使用有角度的承诺,但出于此目的,任何带有回调的javascript代码都是相同的。

someObject.doSomething(param1, function(result1) {
  console.log("Got result from doSomething: " + result1);
  result.doSomethingElse(param2, function(result2) {
    console.log("Got result from doSomethingElse: " + result2);
  }, function(error2) {
    console.log("Got error from doSomethingElse: " + error2);
  });
}, function(error1) {
  console.log("Got error from doSomething: " + error1);
});

现在,您可能想要通过定义记录错误的函数来整理代码,并保留错误的来源以进行调试。这是您继续重构代码的方式:

someObject.doSomething(param1, function (result1) {
  console.log("Got result from doSomething: " + result1);
  result.doSomethingElse(param2, function (result2) {
    console.log("Got result from doSomethingElse: " + result2);
  }, handleError.bind(null, "doSomethingElse"));
}, handleError.bind(null, "doSomething"));

/*
 * Log errors, capturing the error of a callback and prepending an id
 */
var handleError = function (id, error) {
  var id = id || "";
  console.log("Got error from " + id + ": " + error);
};

调用函数仍将在回调函数参数之后添加错误参数。


0

我一直在寻找相同的东西,并最终找到解决方案,如果有人想通过这里,这是一个简单的示例。

var FA = function(data){
   console.log("IN A:"+data)
   FC(data,"LastName");
};
var FC = function(data,d2){
   console.log("IN C:"+data,d2)
};
var FB = function(data){
   console.log("IN B:"+data);
    FA(data)
};
FB('FirstName')

还贴在其他问题在这里


0

让我给您一个使用回调的非常简单的Node.js样式示例:

/**
 * Function expects these arguments: 
 * 2 numbers and a callback function(err, result)
 */
var myTest = function(arg1, arg2, callback) {
  if (typeof arg1 !== "number") {
    return callback('Arg 1 is not a number!', null); // Args: 1)Error, 2)No result
  }
  if (typeof arg2 !== "number") {
    return callback('Arg 2 is not a number!', null); // Args: 1)Error, 2)No result
  }
  if (arg1 === arg2) {
    // Do somethign complex here..
    callback(null, 'Actions ended, arg1 was equal to arg2'); // Args: 1)No error, 2)Result
  } else if (arg1 > arg2) {
    // Do somethign complex here..
    callback(null, 'Actions ended, arg1 was > from arg2'); // Args: 1)No error, 2)Result
  } else {
    // Do somethign else complex here..
    callback(null, 'Actions ended, arg1 was < from arg2'); // Args: 1)No error, 2)Result
  }
};


/**
 * Call it this way: 
 * Third argument is an anonymous function with 2 args for error and result
 */
myTest(3, 6, function(err, result) {
  var resultElement = document.getElementById("my_result");
  if (err) {
    resultElement.innerHTML = 'Error! ' + err;
    resultElement.style.color = "red";
    //throw err; // if you want
  } else {
    resultElement.innerHTML = 'Result: ' + result;
    resultElement.style.color = "green";
  }
});

以及将呈现结果的HTML:

<div id="my_result">
  Result will come here!
</div>

您可以在这里使用它:https : //jsfiddle.net/q8gnvcts/-例如,尝试传递字符串而不是数字:myTest('some string',6,6,function(err,result) ..并查看结果。

我希望该示例有所帮助,因为它代表了回调函数的基本概念。


0
function tryMe(param1, param2) {
  console.log(param1 + " and " + param2);
}

function tryMe2(param1) {
  console.log(param1);
}

function callbackTester(callback, ...params) {
  callback(...params);
}



callbackTester(tryMe, "hello", "goodbye");

callbackTester(tryMe2, "hello");

阅读有关传播语法的更多信息


0
//Suppose function not taking any parameter means just add the GetAlterConfirmation(function(result) {});
GetAlterConfirmation('test','messageText',function(result) {
                        alert(result);
    }); //Function into document load or any other click event.


function GetAlterConfirmation(titleText, messageText, _callback){
         bootbox.confirm({
                    title: titleText,
                    message: messageText,
                    buttons: {
                        cancel: {
                            label: '<i class="fa fa-times"></i> Cancel'
                        },
                        confirm: {
                            label: '<i class="fa fa-check"></i> Confirm'
                        }
                    },
                    callback: function (result) {
                        return _callback(result); 
                    }
                });

1
请添加您在做什么以及原因的解释:)
Preston Badeer

好的,我将从下一个答案开始,对不起,因为这是我的第一个答案。
Santhos Jery
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.