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

JavaScript: Passing parameters to a callback function

提问人:vitto 提问时间:8/11/2010 最后编辑:Teoccivitto 更新时间:7/25/2023 访问量:589744

问:

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

这是我的尝试:

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

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

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

JavaScript 回调 参数传递

评论

12赞 Daniel Vassallo 8/11/2010
你正在做的事情应该有效。你有什么问题?
1赞 Sarfraz 8/11/2010
你的代码工作正常,有什么问题?
1赞 Hristo 8/11/2010
它应该可以工作...jsfiddle.net/QXQZj
0赞 vitto 8/11/2010
对不起,这是我在主代码语法上的错,我以为是因为这是我第一次在 JavaScript 中使用回调
0赞 ThorSummoner 1/24/2015
如果你想向回调添加参数,但不能改变调用它的内容(因为你没有权力改变参数顺序,你可以用 JS bind 预绑定一些回调参数,正如我在这个答案中所示: stackoverflow.com/a/28120741/1695680

答:

318赞 Simon Scarfe 8/11/2010 #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

评论

63赞 Steven 8/11/2010
只要我们本着通用的精神,因为函数体是可以扩展到两个参数场景之外的。callback.apply(arguments)callbackTester
1赞 vitto 8/11/2010
对不起,这是主代码中的语法错误,我以为是因为这是我第一次在 JavaScript 中使用回调,您帮助我理解这不是问题,并看到了一个很好的例子。
3赞 antoine 6/27/2015
仅供参考,使用匿名函数(Marimuthu 的答案)或 .bind()(Andy 的答案)是将参数传递给回调的更简洁的方法。
1赞 Eagle_ 7/14/2022
let args = Object.values(arguments); args.shift(); callback(...args);由于 callbackTester 正文允许可变数量的参数
79赞 Andy E 8/11/2010 #2

您的问题不清楚。如果你想知道如何以更简单的方式做到这一点,你应该看看 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))); 
    }; 
  };
}

bind() - PrototypeJS 文档

评论

0赞 sje397 8/11/2010
出于兴趣,和 和有什么不一样?Array.prototype.slice.call(arguments)arguments.slice()
7赞 Andy E 8/11/2010
@sje397:arguments 不是一个*真正的*数组,所以它没有 slice() 方法。但是,Array.prototype 上的 slice() 方法是有意泛型的,因此您可以传递任何具有数字索引和 length 属性的对象,它就会起作用。
2赞 antoine 6/27/2015
这是最优雅的答案
0赞 Le Droid 1/23/2016
这个 .bind() 真的很棒,它扩展了很多回调的使用和简单性。作为理解它的基本示例,如果您有:f = function(arg1,arg2){alert(arg1+arg2);}.bind(this,"abc"); f("def") // Gives "abcdef"
0赞 Vishnu Mishra 8/10/2016
这真的是一个grt答案。太棒了,对我来说效果很好。谢谢:)
246赞 Marimuthu Madasamy 8/11/2010 #3

这也将起作用:

// 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赞 Michael Khalili 7/14/2014
这很好用,因为它还允许匿名函数传入如下参数: callbackTester (function(data) {tryMe(data, “hello”, “goodbye”);
0赞 Katrina 5/21/2015
我还想检查回调实际上是否是一个函数。if (typeof window[callback] == 'function') window[callback].call(this);
0赞 DhineshYes 10/11/2020
这是简单和最好的答案。
0赞 vincent thorpe 9/9/2022
如果你处于循环中。参数将失去其价值,这仅在调用一次后有效,并且参数是连续的。最好使用 .bind() 方法
14赞 Blake Mills 9/19/2013 #4

当你有一个回调,该回调将由代码以外的其他内容调用,并且具有特定数量的参数,并且想要传入额外的参数时,你可以传递一个包装函数作为回调,并在包装器内部传递额外的参数。

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赞 Alan McCune 10/24/2013 #5

将作为/与参数一起传递的“子”函数包装在函数包装器中,以防止在调用“父”函数时计算它们。

function outcome(){
    return false;
}

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

process(function(){alert("OKAY");},function(){alert("OOPS");})
5赞 adamsko 5/12/2015 #6

从具有任意数量的参数和回调上下文的问题中编码:

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
1赞 Juangui Jordán 9/29/2016 #7

一个新版本,适用于回调将由其他函数调用的方案,而不是你自己的代码,并且你想要添加其他参数。

例如,让我们假设您有很多嵌套调用,其中包含成功和错误回调。在此示例中,我将使用 angular promises,但任何带有回调的 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 参数。

0赞 Code_Crash 1/18/2017 #8

我一直在寻找同样的事情并最终得到解决方案,如果有人想经历这个,这里有一个简单的例子。

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

也在这里发布了另一个问题

4赞 user6748331 7/9/2017 #9

使用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>

20赞 Zeeman Chen 4/6/2018 #10

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

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

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

callbackTester(tryMe,['hello','goodbye']);
1赞 Vlado 2/24/2019 #11

让我给你一个非常简单的 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).. 并查看结果。

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

1赞 Dmitry Grinko 7/30/2019 #12
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");

阅读有关 Spread 语法的更多信息

评论

2赞 Franck 9/3/2021
对我来说最好的答案。最实用。
0赞 Santhos Jery 10/31/2019 #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); 
                    }
                });

评论

1赞 Preston Badeer 10/31/2019
请解释您正在做什么以及为什么:)
0赞 Santhos Jery 11/4/2019
好的,我会从我的下一个答案开始,对不起,因为这是我的第一个答案。
1赞 Teocci 9/30/2021 #14

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

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

现在,其他一些开发人员可能也认为我们可以使用“数组”。那很好,但我们应该小心。 不是一个真正的数组,而是一个具有 length 属性的类似数组的对象。argumentsarguments

下面是使用 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');

3赞 Fru 6/6/2022 #15

最近面对这个问题,要得到它(特别是如果父函数有多个参数做与回调无关的不同事情,就是将回调与其参数一起放在作为参数传递的箭头函数中。

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

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

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

...或者只是如果你没有多个参数做其他事情。

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

function callbackTester(callback) {
  callback();
}

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

1赞 Victor Santizo 8/28/2022 #16

只需使用 bind() 函数,该函数主要用于设置值。但是,我们也可以使用它来传递参数而不调用函数,因为返回一个带有提供的参数序列的新函数。thisbind()

例:

function foo(param1, param2, param3) {
  console.log(param1, param2, param3);
}

setTimeout(foo.bind(null, 'foo', 'bar', 'baz'), 1000);

在上面的代码片段中,setTimeout 函数需要 2 个参数,即回调函数和调用函数的最短时间(以毫秒为单位),因此在传递回调函数时,我们将使用 bind 并指定参数

注意:bind 的第一个参数是我们要设置的值,因为我们对此不感兴趣,所以 bind 中的后续参数将成为回调的参数。thisnull

0赞 Rakibul Hasan 7/25/2023 #17

您可以使用数组传递参数,我希望这对您有用,谢谢

function tryMe(params) {
    alert(params[0] + " and " + params[1]);
  }
  
  function callbackTester(callback, params) {
    callback(params);
  }
  
  callbackTester(tryMe, ["hello", "goodbye"]);

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