J'essaie de passer un paramètre à une fonction utilisée comme rappel, comment puis-je faire cela?
function tryMe (param1, param2) {
alert (param1 + " and " + param2);
}
function callbackTester (callback, param1, param2) {
callback (param1, param2);
}
callbackTester (tryMe, "hello", "goodbye");
Si vous voulez quelque chose de légèrement plus général, vous pouvez utiliser la variable arguments comme ceci:
function tryMe (param1, param2) {
alert(param1 + " and " + param2);
}
function callbackTester (callback) {
callback (arguments[1], arguments[2]);
}
callbackTester (tryMe, "hello", "goodbye");
Mais sinon, votre exemple fonctionne bien (les arguments [0] peuvent être utilisés à la place du rappel dans le testeur)
Cela fonctionnerait aussi:
// callback function
function tryMe (param1, param2) {
alert (param1 + " and " + param2);
}
// callback executer
function callbackTester (callback) {
callback();
}
// test function
callbackTester (function() {
tryMe("hello", "goodbye");
});
Un autre scénario:
// 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);
});
Votre question n'est pas claire. Si vous demandez comment vous pouvez le faire d'une manière plus simple, consultez la méthode .bind () d'ECMAScript 5th edition, qui est membre de Function.prototype. En l'utilisant, vous pouvez faire quelque chose comme ceci:
function tryMe (param1, param2) {
alert (param1 + " and " + param2);
}
function callbackTester (callback) {
callback();
}
callbackTester(tryMe.bind(null, "hello", "goodbye"));
Vous pouvez également utiliser le code suivant, qui ajoute la méthode si elle n'est pas disponible dans le navigateur actuel:
// 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)));
};
};
}
Lorsque vous avez un rappel qui sera appelé par quelque chose d'autre que votre code avec un nombre spécifique de paramètres et que vous souhaitez transmettre des paramètres supplémentaires, vous pouvez passer une fonction wrapper en tant que rappel et à l'intérieur du wrapper, passer le ou les paramètres supplémentaires.
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
}
Enveloppez les fonctions 'enfant' passées en tant que/avec des arguments dans les enveloppes de fonctions pour éviter leur évaluation lors de l'appel de la fonction 'parent'.
function outcome(){
return false;
}
function process(callbackSuccess, callbackFailure){
if ( outcome() )
callbackSuccess();
else
callbackFailure();
}
process(function(){alert("OKAY");},function(){alert("OOPS");})
Code d'une question avec un nombre quelconque de paramètres et un contexte de rappel:
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
Si vous n'êtes pas sûr du nombre de paramètres que vous allez passer dans les fonctions de rappel. En utilisant appliquer.
function tryMe (param1, param2) {
alert (param1 + " and " + param2);
}
function callbackTester(callback,params){
callback.apply(this,params);
}
callbackTester(tryMe,['hello','goodbye']);
Utilisez la fonction curry comme dans cet exemple simple.
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>
Laissez-moi vous donner un exemple très simple de style Node.js d'utilisation d'un rappel:
/**
* 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";
}
});
et le HTML qui rendra le résultat:
<div id="my_result">
Result will come here!
</div>
Vous pouvez y jouer ici: https://jsfiddle.net/q8gnvcts/ - par exemple, essayez de passer une chaîne au lieu du nombre: myTest ('une chaîne', 6, fonction (err, résultat) .. et voir le résultat.
J'espère que cet exemple aide car il représente l'idée de base des fonctions de rappel.
Une nouvelle version du scénario dans laquelle le rappel est appelé par une autre fonction, et non par votre propre code, et vous souhaitez ajouter des paramètres supplémentaires.
Par exemple, supposons que vous avez beaucoup d'appels imbriqués avec des rappels de succès et d'erreur. Je vais utiliser des promesses angulaires pour cet exemple, mais tout code javascript avec des rappels serait le même pour les besoins.
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);
});
Vous pouvez maintenant désencombrer votre code en définissant une fonction permettant de consigner les erreurs, en conservant l'origine de l'erreur à des fins de débogage. Voici comment procéder pour refactoriser votre 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);
};
La fonction appelante ajoutera toujours le paramètre error après vos paramètres de fonction de rappel.
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");
en savoir plus à propos de la syntaxe de propagation
Je cherchais la même chose et je trouve la solution. En voici un exemple simple si quelqu'un veut passer par là.
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')
Également publié sur l'autre question ici