简体   繁体   English

JavaScript:将参数传递给回调 function

[英]JavaScript: Passing parameters to a callback function

I'm trying to pass some parameter to a function used as callback , how can I do that?我正在尝试将一些参数传递给用作callback的 function ,我该怎么做?

This is my try:这是我的尝试:

 function tryMe(param1, param2) { alert(param1 + " and " + param2); } function callbackTester(callback, param1, param2) { callback(param1, param2); } callbackTester(tryMe, "hello", "goodbye");

If you want something slightly more general, you can use the arguments variable like so:如果你想要更一般的东西,你可以像这样使用参数变量:

 function tryMe(param1, param2) { alert(param1 + " and " + param2); } function callbackTester(callback) { callback(arguments[1], arguments[2]); } callbackTester(tryMe, "hello", "goodbye");

But otherwise, your example works fine ( arguments[0] can be used in place of callback in the tester)但除此之外,您的示例工作正常( arguments[0]可用于代替测试器中的callback

This would also work:这也可以:

 // callback function function tryMe(param1, param2) { alert(param1 + " and " + param2); } // callback executer function callbackTester(callback) { callback(); } // test function callbackTester(function() { tryMe("hello", "goodbye"); });

Another Scenario :另一个场景:

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

Your question is unclear.你的问题不清楚。 If you're asking how you can do this in a simpler way, you should take a look at the ECMAScript 5th edition method .bind() , which is a member of Function.prototype .如果您要问如何以更简单的方式执行此操作,您应该查看 ECMAScript 第 5 版方法.bind() ,它是Function.prototype的成员。 Using it, you can do something like this:使用它,您可以执行以下操作:

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

function callbackTester (callback) {
    callback();
}

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

You can also use the following code, which adds the method if it isn't available in the current browser:您还可以使用以下代码,如果该方法在当前浏览器中不可用,则会添加该方法:

// 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 bind() - PrototypeJS 文档

If you are not sure how many parameters are you going to be passed into callback functions, use apply function.如果您不确定将有多少参数传递给回调函数,请使用apply函数。

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

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

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

When you have a callback that will be called by something other than your code with a specific number of params and you want to pass in additional params you can pass a wrapper function as the callback and inside the wrapper pass the additional param(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
}

Wrap the 'child' function(s) being passed as/with arguments within function wrappers to prevent them being evaluated when the 'parent' function is called.在函数包装器中包装作为/带有参数传递的“子”函数,以防止在调用“父”函数时对它们进行评估。

function outcome(){
    return false;
}

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

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

Code from a question with any number of parameters and a callback context:来自具有任意数量参数和回调上下文的问题的代码:

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

Use curried function as in this simple example.在这个简单的例子中使用柯里化函数。

 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>

A new version for the scenario where the callback will be called by some other function, not your own code, and you want to add additional parameters.一个新版本,用于回调将由某个其他函数而不是您自己的代码调用的场景,并且您想要添加其他参数。

For example, let's pretend that you have a lot of nested calls with success and error callbacks.例如,假设您有很多带有成功和错误回调的嵌套调用。 I will use angular promises for this example but any javascript code with callbacks would be the same for the purpose.我将在此示例中使用 angular 承诺,但任何带有回调的 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);
});

Now you may want to unclutter your code by defining a function to log errors, keeping the origin of the error for debugging purposes.现在,您可能希望通过定义一个记录错误的函数来整理代码,保留错误的来源以进行调试。 This is how you would proceed to refactor your code:这是您重构代码的方式:

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

The calling function will still add the error parameter after your callback function parameters.调用函数仍会在回调函数参数之后添加错误参数。

Let me give you a very plain Node.js style example of using a callback:让我给你一个使用回调的非常简单的 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";
  }
});

and the HTML that will render the result:以及将呈现结果的 HTML:

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

You can play with it here: https://jsfiddle.net/q8gnvcts/ - for example try to pass string instead of number: myTest('some string', 6, function(err, result) .. and see the result.你可以在这里玩它: https : //jsfiddle.net/q8gnvcts/ - 例如尝试传递字符串而不是数字: myTest('some string', 6, function(err, result) ..并查看结果。

I hope this example helps because it represents the very basic idea of callback functions.我希望这个例子有帮助,因为它代表了回调函数的基本思想。

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 about the spread syntax 阅读有关传播语法的更多信息

Faced this recently, to get it(especially if the parent function has multiple arguments doing different stuffs not related to the callback, is to have the callback placed with its argument in an arrow function passed as an argument.最近面对这个,要得到它(特别是如果父 function 有多个 arguments 做与回调无关的不同事情,就是将回调放置在箭头 ZC1C425268E68385D1AB5074C17A9 中作为参数传递。

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

function callbackTester(callback, someArg, AnotherArg) {
  callback();
  
}

callbackTester(()=> tryMe("hello", "goodbye"), "someArg", "AnotherArg");

...or simply if you dont have multiple arguments doing other stuff. ...或者只是如果您没有多个 arguments 做其他事情。

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

function callbackTester(callback) {
  callback();
}

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

I was looking for the same thing and end up with the solution and here it's a simple example if anybody wants to go through this.我一直在寻找同样的东西并最终得到解决方案,如果有人想通过这个,这是一个简单的例子。

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

Also posted on the other question here也在这里发布了另一个问题

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

I'm trying to pass some parameter to a function used as callback , how can I do that?我试图将一些参数传递给用作callback的函数,我该怎么做?

I think he is implying that he wants to call the function this callbackTester(tryMe, "hello", "goodbye") .我认为他是在暗示他想调用这个函数callbackTester(tryMe, "hello", "goodbye") To do this we can use the Rest Operator (...) .为此,我们可以使用Rest Operator (...) This operator takes the arguments that a function receives and dumps them into a real array that we will use to access in our callback function.该运算符获取函数接收的参数并将它们转储到我们将在callback函数中访问的真实数组中。

Now, some other developers might also argue that we could use the arguments "array".现在,其他一些开发人员可能也会争辩说我们可以使用arguments “array”。 That will be fine, but we should be careful with it.那会好的,但我们应该小心。 arguments is not a real array but an array-like object with a length property. arguments不是真正的数组,而是具有长度属性的类数组对象。

Here is a working snippet using the Rest Operator:这是使用 Rest 运算符的工作片段:

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

Just use the bind() function which is primarily used to set the this value.只需使用主要用于设置this值的bind() function。 However, we can also use it to pass parameters without calling the function due to bind() returning a new function with the sequence of arguments provided.但是,我们也可以使用它来传递参数而不调用 function,因为bind()返回一个新的 function 并提供了 arguments 的序列。

Example:例子:

 function foo(param1, param2, param3) { console.log(param1, param2, param3); } setTimeout(foo.bind(null, 'foo', 'bar', 'baz'), 1000);

In the snippet above, the setTimeout function takes 2 arguments, the callback function and a minimum time in ms for the function to be called, so when passing the callback function we're going to use bind and specify the parameters In the snippet above, the setTimeout function takes 2 arguments, the callback function and a minimum time in ms for the function to be called, so when passing the callback function we're going to use bind and specify the parameters

Note: The first parameter of bind is the value that we want to set for this , and because we're not interested on that, null was passed, the subsequent parameters in bind are going to be the parameters for the callback.注意:bind 的第一个参数是我们要设置的this的值,因为我们对此不感兴趣,所以传递了null ,bind 中的后续参数将作为回调的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM