2010-08-11 19 views
215

Ich versuche, einen Parameter an eine Funktion als Rückruf übergeben, wie kann ich das tun?JavaScript: Übergabe von Parametern an eine Callback-Funktion

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

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

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

Was Sie tun, sollte funktionieren. Welche Probleme haben Sie? –

+1

Ihr Code funktioniert gut, was ist das Problem? – Sarfraz

+1

Es sollte funktionieren ... http://jsfiddle.net/QXQZj/ – Hristo

Antwort

186

Wenn Sie etwas etwas allgemeinere möchten, können Sie die Argumente verwenden Variable wie so:

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

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

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

Aber ansonsten Ihr Beispiel funktioniert gut (Argumente [0] kann anstelle von Callback verwendet werden im Tester)

+42

Solange wir im Geiste sind, allgemein zu sein, ist 'callback.apply (arguments)' als Funktionskörper für 'callbackTester' über das Zwei-Argument-Szenario hinaus erweiterbar. –

+0

Entschuldigung, es war ein Syntaxfehler im Hauptcode, ich dachte, das war, weil dies das erste Mal, dass ich einen Rückruf in JavaScript verwende, hast du mir geholfen zu verstehen, es war nicht das Problem, und ein gutes Beispiel zu sehen . – vitto

+1

FYI, eine anonyme Funktion (Marimuthus Antwort) oder .bind() (Andys Antwort) sind viel sauberere Wege, um Argumente an einen Callback zu übergeben. – antoine

50

Ihre Frage ist unklar. Wenn Sie sich fragen, wie Sie das einfacher machen können, sollten Sie sich die ECMAScript 5th Edition-Methode .bind() ansehen, die ein Mitglied von Function.prototype ist. Mit ihm können Sie etwas tun:

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

function callbackTester (callback) { 
    callback(); 
} 

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

Sie können auch den folgenden Code verwenden, die das Verfahren ergänzt, wenn es nicht in dem aktuellen 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

+0

Interessant, was ist der Unterschied zwischen 'Array.prototype.slice.call (Argumente)' und 'arguments.slice()'? – sje397

+6

@ sje397: * Argumente * ist kein \ * real \ * Array, also hat es keine * slice() * Methode. Die * slice() * -Methode für den * Array.prototype * ist jedoch absichtlich generisch, so dass Sie jedes Objekt mit numerischen Indizes und einer * length * -Eigenschaft übergeben können. –

+0

Aha. Prost .... – sje397

176

Dies würde auch:

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

// callback executer 
function callbackTester (callback) { 
    callback(); 
} 

// test function 
callbackTester (function() { 
    tryMe("hello", "goodbye"); 
}); 

Ein weiteres Szenario:

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

+1. Das Übergeben von Schließungen/anonymen Funktionen ist der beste Weg. –

+0

Wie würdest du dann Interval löschen? –

+2

Das funktioniert gut, weil es auch die anonyme Funktion ermöglicht, Parameter wie folgt zu übergeben: callbackTester (Funktion (Daten) {tryMe (Daten, "Hallo", "Auf Wiedersehen");}); –

9

Wenn Sie einen Rückruf haben, die durch etwas anderes als Ihren Code mit einer bestimmten Anzahl von params und möchten Sie weitergeben können in zusätzlichen params passieren genannt wird Wrapper-Funktion als Callback und innerhalb des Wrappers übergeben die zusätzlichen 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 
} 
4

Wickeln Sie das ‚Kind‘ Funktion (en) als/mit Argumenten in Funktion Wrapper übergeben werden, damit sie nicht ausgewertet werden, wenn die ‚Eltern‘ Funktion aufgerufen wird.

function outcome(){ 
    return false; 
} 

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

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

-Code aus einer Frage mit einem beliebigen Anzahl von Parametern und einem Callback-Kontext:

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 
0

Eine neue Version für das Szenario, in dem der Rückruf wird durch eine andere Funktion aufgerufen wird, nicht Ihren eigenen Code, und Sie möchten zusätzliche Parameter hinzufügen.

Zum Beispiel, täuschen wir vor, dass Sie viele geschachtelte Aufrufe mit Erfolg und Fehler Callbacks haben. Ich werde eckige Versprechungen für dieses Beispiel verwenden, aber jeder Javascript-Code mit Rückrufen wäre für diesen Zweck derselbe.

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

Jetzt können Sie Ihren Code unclutter durch eine Funktion definieren, Fehler zu protokollieren, für Debugging-Zwecke, den Ursprung des Fehlers zu halten.Dies ist, wie würden Sie gehen Ihren Code Refactoring:

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

Die Aufruffunktion wird immer noch die Fehlerparameter nach dem Callback-Funktion Parameter hinzuzufügen.

0

Ich war auf der Suche nach der gleichen Sache und am Ende mit der Lösung und hier ist es ein einfaches Beispiel, wenn jemand dies durchmachen will.

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

Auch auf der anderen Frage here

posted
1

Verwenden curried Funktion wie in diesem einfachen Beispiel.

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>

Verwandte Themen