JavaScript: передача параметров функции обратного вызова
Я пытаюсь передать некоторый параметр функции, используемой как обратный вызов, как я могу это сделать?
function tryMe (param1, param2) {
alert (param1 + " and " + param2);
}
function callbackTester (callback, param1, param2) {
callback (param1, param2);
}
callbackTester (tryMe, "hello", "goodbye");
Ответы
Ответ 1
Если вы хотите что-то более общее, вы можете использовать переменную arguments так:
function tryMe (param1, param2) {
alert(param1 + " and " + param2);
}
function callbackTester (callback) {
callback (arguments[1], arguments[2]);
}
callbackTester (tryMe, "hello", "goodbye");
Но в остальном ваш пример отлично работает (аргументы [0] могут использоваться вместо обратного вызова в тестере)
Ответ 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);
});
Ответ 3
Твой вопрос непонятен. Если вы спрашиваете, как вы можете сделать это более простым способом, вы должны взглянуть на метод 5-го издания 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
Ответ 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
}
Ответ 5
Если вы не знаете, сколько параметров вы собираетесь передать в функции обратного вызова. Использование применяется.
function tryMe (param1, param2) {
alert (param1 + " and " + param2);
}
function callbackTester(callback,params){
callback.apply(this,params);
}
callbackTester(tryMe,['hello','goodbye']);
Ответ 6
Оберните функцию "ребенка", передаваемую как/с аргументами в оболочках функций, чтобы предотвратить их оценку при вызове функции "parent".
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
Используйте эту функцию как в этом простом примере.
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 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);
};
Вызывающая функция по-прежнему будет добавлять параметр ошибки после параметров функции обратного вызова.
Ответ 10
Я искал одно и то же, и в итоге получилось решение, и вот это простой пример, если кто-то хочет пройти через это.
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')
Также опубликовано по другому вопросу здесь
Ответ 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).. и посмотрите результат.
Я надеюсь, что этот пример поможет, потому что он представляет очень основную идею функций обратного вызова.
Ответ 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");
подробнее о синтаксисе распространения