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

Posted

技术标签:

【中文标题】JavaScript:将参数传递给回调函数【英文标题】:JavaScript: Passing parameters to a callback function 【发布时间】:2011-03-28 09:03:48 【问题描述】:

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

这是我的尝试:

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


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


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

【问题讨论】:

你正在做的应该工作。你有什么问题? 您的代码运行良好,有什么问题? 它应该可以工作...jsfiddle.net/QXQZj 对不起,主要代码语法是我的错,我以为这是因为这是我第一次在 javascript 中使用回调 如果你想给回调添加参数但不能改变调用它的东西(因为你没有权力改变参数顺序,你可以用JS预先绑定一些回调参数绑定,正如我在这个答案中所展示的:***.com/a/28120741/1695680 【参考方案1】:

如果你想要更通用的东西,你可以像这样使用 arguments 变量:

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


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


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

但除此之外,您的示例运行良好(arguments[0] 可以在测试器中用于代替 callback

【讨论】:

只要我们本着通用的精神,callback.apply(arguments) 作为callbackTester 的函数体就可以扩展到两个参数场景之外。 对不起,这是主代码中的语法错误,我以为这是因为这是我第一次在 JavaScript 中使用回调,您帮助我理解了这不是问题,并看到一个很好的例子。 仅供参考,使用匿名函数(Marimuthu 的回答)或 .bind()(Andy 的回答)是将参数传递给回调的更简洁的方法。【参考方案2】:

这也可以:

// 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);
);

【讨论】:

这很好用,因为它还允许匿名函数像这样传递参数:callbackTester (function(data) tryMe(data, "hello", "goodbye"); );跨度> 我还想检查回调实际上是一个函数。 if (typeof window[callback] == 'function') window[callback].call(this); 这是最简单的最佳答案。【参考方案3】:

您的问题不清楚。如果您问如何以更简单的方式做到这一点,您应该查看 ECMAScript 第 5 版方法 .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))); 
    ; 
  ;

Example

bind() - PrototypeJS Documentation

【讨论】:

出于兴趣,Array.prototype.slice.call(arguments)arguments.slice()有什么区别? @sje397: arguments 不是 *real* 数组,因此它没有 slice() 方法。但是,Array.prototype 上的 slice() 方法是故意通用的,因此您可以传递任何具有数字索引和 length 的对象财产,它会工作。 这是最优雅的答案 这个 .bind() 真的很棒并且扩展了很多回调的使用和简单性。作为理解它的基本示例,如果你有:f = function(arg1,arg2)alert(arg1+arg2);.bind(this,"abc");f("def") // Gives "abcdef" 这真是一个很好的答案。太棒了,对我来说工作得很好。谢谢你:)【参考方案4】:

如果您不确定要向回调函数传递多少参数,请使用apply 函数。

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


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


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

【讨论】:

【参考方案5】:

当您有一个回调,该回调将由具有特定数量参数的代码以外的其他东西调用,并且您想要传递额外的参数,您可以传递一个包装器函数作为回调,并在包装​​器内部传递额外的参数( s)。

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

【讨论】:

【参考方案6】:

在函数包装器中包装作为/带有参数传递的“子”函数,以防止在调用“父”函数时对其进行评估。

function outcome()
    return false;


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


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

【讨论】:

【参考方案7】:

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

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

【讨论】:

【参考方案8】:

在这个简单的例子中使用 curried 函数。

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>

【讨论】:

【参考方案9】:

一个新版本,用于回调将由其他函数调用,而不是您自己的代码,并且您想添加其他参数的场景。

例如,假设您有很多带有成功和错误回调的嵌套调用。我将在此示例中使用 Angular Promise,但任何带有回调的 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);
;

调用函数还是会在你的回调函数参数后面加上error参数。

【讨论】:

【参考方案10】:

让我给你一个使用回调的非常简单的 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, function(err, result).. 看看结果。

我希望这个例子对你有所帮助,因为它代表了回调函数的基本概念。

【讨论】:

【参考方案11】:
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");

read more关于扩展语法

【讨论】:

对我来说最好的答案。最实用。【参考方案12】:

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

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')

也发布在另一个问题here

【讨论】:

【参考方案13】:
//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); 
                    
                );

【讨论】:

请解释你在做什么以及为什么:) 好的,我会从我的下一个答案开始,对以上内容感到抱歉,因为这是我的第一个答案。【参考方案14】:

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

我认为他暗示他想将此函数称为callbackTester(tryMe, "hello", "goodbye")。为此,我们可以使用the Rest Operator (...)。此运算符接受函数接收的参数并将它们转储到 真实数组 中,我们将使用该数组在 callback 函数中访问。

现在,其他一些开发人员也可能会争辩说我们可以使用arguments“数组”。这很好,但我们应该小心。 arguments 不是真正的数组,而是具有长度属性的类数组对象。

这是一个使用 Rest Operator 的工作 sn-p:

function tryMe(params) 
  console.log(params.join(', '));


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


callbackTester(tryMe, 'hello', 'goodbye', 'hi again');
callbackTester(tryMe, 'hello', 'goodbye');
callbackTester(tryMe, 'hello');

【讨论】:

以上是关于JavaScript:将参数传递给回调函数的主要内容,如果未能解决你的问题,请参考以下文章

什么是回调函数

将参数传递给 UIcontrol 回调函数

将 VB 函数回调作为参数传递给 .NET

如何在 Javascript .filter() 方法中将额外参数传递给回调函数?

角度拖放-如何将参数传递给onStart回调函数

Javascript:将自定义参数传递给回调函数