it-swarm.com.de

Wie erkläre ich Rückrufe im Klartext? Wie unterscheiden sie sich vom Aufrufen einer Funktion von einer anderen Funktion?

Wie lassen sich Rückrufe im Klartext erklären? Wie unterscheiden sie sich vom Aufrufen einer Funktion von einer anderen Funktion, die einen Kontext von der aufrufenden Funktion verwendet? Wie kann ihre Macht einem unerfahrenen Programmierer erklärt werden?

331
Yahoo-Me

Oft muss eine Anwendung je nach Kontext/Zustand unterschiedliche Funktionen ausführen. Dazu verwenden wir eine Variable, in der wir die Informationen über die aufzurufende Funktion speichern würden. Je nach Bedarf setzt die Anwendung diese Variable mit den Informationen über die aufzurufende Funktion und ruft die Funktion mit derselben Variablen auf.

In Javascript ist das Beispiel unten. Hier verwenden wir das Argument method als Variable, in der wir Informationen über die Funktion speichern.

function processArray(arr, callback) {
    var resultArr = new Array(); 
    for (var i = arr.length-1; i >= 0; i--)
        resultArr[i] = callback(arr[i]);
    return resultArr;
}

var arr = [1, 2, 3, 4];
var arrReturned = processArray(arr, function(arg) {return arg * -1;});
// arrReturned would be [-1, -2, -3, -4]
113
Niraj Nawanit

Ich werde versuchen, das so einfach wie möglich zu halten. Ein "Rückruf" ist eine Funktion, die von einer anderen Funktion aufgerufen wird, die die erste Funktion als Parameter verwendet. Häufig ist ein "Rückruf" eine Funktion, die aufgerufen wird, wenn etwas passiert. Das etwas kann im Programmierer-Sprechen ein "Ereignis" genannt werden.

Stellen Sie sich dieses Szenario vor: Sie erwarten ein Paket in ein paar Tagen. Das Paket ist ein Geschenk für Ihren Nachbarn. Sobald Sie das Paket erhalten haben, möchten Sie, dass es den Nachbarn übergeben wird. Sie sind nicht in der Stadt und hinterlassen Anweisungen für Ihren Ehepartner.

Sie könnten ihnen sagen, sie sollen das Paket holen und zu den Nachbarn bringen. Wenn Ihr Ehepartner so dumm war wie ein Computer, saßen sie an der Tür und warteten auf das Paket, bis es kam (und taten sonst nichts), und wenn es kam, brachten sie es zu den Nachbarn. Aber es gibt einen besseren Weg. Sagen Sie Ihrem Ehepartner, dass er das Paket EINMAL erhalten soll und über die Nachbarn bringen soll. Dann können sie normal weiterleben, BIS sie das Paket erhalten.

In unserem Beispiel ist der Empfang des Pakets das "Ereignis" und das Bringen zu den Nachbarn der "Rückruf". Ihr Ehepartner "führt" Ihre Anweisungen aus, um das Paket nur dann zu übergeben , wenn das Paket eintrifft. Viel besser!

Diese Art des Denkens ist im täglichen Leben offensichtlich, aber Computer haben nicht den gleichen gesunden Menschenverstand. Überlegen Sie, wie Programmierer normalerweise in eine Datei schreiben:

fileObject = open(file)
# now that we have WAITED for the file to open, we can write to it
fileObject.write("We are writing to the file.")
# now we can continue doing the other, totally unrelated things our program does

Hier WARTEN wir darauf, dass die Datei geöffnet wird, bevor wir darauf schreiben. Dies "blockiert" den Ablauf der Ausführung, und unser Programm kann keine der anderen Aufgaben ausführen, die es möglicherweise ausführen muss! Was wäre, wenn wir dies stattdessen tun könnten:

# we pass writeToFile (A CALLBACK FUNCTION!) to the open function
fileObject = open(file, writeToFile)
# execution continues flowing -- we don't wait for the file to be opened
# ONCE the file is opened we write to it, but while we wait WE CAN DO OTHER THINGS!

Es stellt sich heraus, dass wir dies mit einigen Sprachen und Frameworks tun. Es ist ziemlich cool! Schauen Sie sich Node.js an, um eine echte Übung mit dieser Art des Denkens zu bekommen.

511
Josh Imhoff

Wie erkläre ich Rückrufe im Klartext?

Im Klartext ist eine Rückruffunktion wie ein Arbeiter , der zu seinem Vorgesetzten "zurückruft", wenn er eine Aufgabe erledigt hat .

Wie unterscheiden sie sich vom Aufrufen einer Funktion von einer anderen Funktion, die einen Kontext von der aufrufenden Funktion verwendet?

Es ist wahr, dass Sie eine Funktion von einer anderen Funktion aufrufen, aber der Schlüssel ist, dass der Rückruf wie ein Objekt behandelt wird, sodass Sie die aufzurufende Funktion basierend auf dem Systemstatus (wie dem Strategy Design Pattern) ändern können.

Wie kann ihre Macht einem unerfahrenen Programmierer erklärt werden?

Die Leistungsfähigkeit von Rückrufen lässt sich leicht auf AJAX-ähnlichen Websites erkennen, die Daten von einem Server abrufen müssen. Das Herunterladen der neuen Daten kann einige Zeit dauern. Ohne Rückrufe würde Ihre gesamte Benutzeroberfläche beim Herunterladen der neuen Daten "einfrieren", oder Sie müssten die gesamte Seite aktualisieren, anstatt nur einen Teil davon. Mit einem Rückruf können Sie ein Bild einfügen, das gerade geladen wird, und es nach dem Laden durch die neuen Daten ersetzen.

Code ohne Rückruf:

function grabAndFreeze() {
    showNowLoading(true);
    var jsondata = getData('http://yourserver.com/data/messages.json');
    /* User Interface 'freezes' while getting data */
    processData(jsondata);
    showNowLoading(false);
    do_other_stuff(); // not called until data fully downloaded
}

function processData(jsondata) { // do something with the data
   var count = jsondata.results ? jsondata.results.length : 0;
   $('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
   $('#results_messages').html(jsondata.results || '(no new messages)');
}

Mit Rückruf:

Hier ist ein Beispiel mit einem Rückruf unter Verwendung von jQuery's getJSON :

function processDataCB(jsondata) { // callback: update UI with results
   showNowLoading(false);
   var count = jsondata.results ? jsondata.results.length : 0;
   $('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
   $('#results_messages').html(jsondata.results || '(no new messages)');
}

function grabAndGo() { // and don't freeze
    showNowLoading(true);
    $('#results_messages').html(now_loading_image);
    $.getJSON("http://yourserver.com/data/messages.json", processDataCB);
    /* Call processDataCB when data is downloaded, no frozen User Interface! */
    do_other_stuff(); // called immediately
}

Mit Verschluss:

Häufig muss der Rückruf über die aufrufende Funktion mit einem state auf closure zugreifen. Dies entspricht dem Worker , der Informationen vom abrufen muss ) Manager , bevor er seine Aufgabe erledigen kann. Um das closure zu erstellen, können Sie die Funktion so einbinden, dass die Daten im aufrufenden Kontext angezeigt werden:

/* Grab messages, chat users, etc by changing dtable. Run callback cb when done.*/
function grab(dtable, cb) { 
    if (null == dtable) { dtable = "messages"; }
    var uiElem = "_" + dtable;
    showNowLoading(true, dtable);
    $('#results' + uiElem).html(now_loading_image);
    $.getJSON("http://yourserver.com/user/"+dtable+".json", cb || function (jsondata) {
       // Using a closure: can "see" dtable argument and uiElem variables above.
       var count = jsondata.results ? jsondata.results.length : 0, 
           counterMsg = ['Fetched', count, 'new', dtable].join(' '),
           // no new chatters/messages/etc
           defaultResultsMsg = ['(no new ', dtable, ')'].join(''); 
       showNowLoading(false, dtable);
       $('#counter' + uiElem).text(counterMsg);
       $('#results'+ uiElem).html(jsondata.results || defaultResultsMsg);
    });
    /* User Interface calls cb when data is downloaded */

    do_other_stuff(); // called immediately
}

Verwendungszweck:

// update results_chatters when chatters.json data is downloaded:
grab("chatters"); 
// update results_messages when messages.json data is downloaded
grab("messages"); 
// call myCallback(jsondata) when "history.json" data is loaded:
grab("history", myCallback); 

Schließung

Schließlich ist hier eine Definition von closure aus Douglas Crockford :

Funktionen können innerhalb anderer Funktionen definiert werden. Die innere Funktion hat Zugriff auf die Variablen und Parameter der äußeren Funktion. Wenn ein Verweis auf eine innere Funktion erhalten bleibt (z. B. als Rückruffunktion), bleiben auch die Variablen der äußeren Funktion erhalten.

Siehe auch:

82
user508994

Ich bin fassungslos zu sehen, dass so viele intelligente Menschen die Realität nicht betonen, dass das Wort "Rückruf" auf zwei inkonsistente Arten verwendet wurde.

In beiden Fällen müssen Sie eine Funktion anpassen, indem Sie einer vorhandenen Funktion zusätzliche Funktionen (eine Funktionsdefinition, anonym oder benannt) übergeben. dh.

customizableFunc(customFunctionality)

Wenn die benutzerdefinierte Funktionalität einfach in den Codeblock eingesteckt wird, haben Sie die Funktion wie folgt angepasst.

    customizableFucn(customFunctionality) {
      var data = doSomthing();
      customFunctionality(data);
      ...
    }

Obwohl diese Art von injizierter Funktionalität oft als "Rückruf" bezeichnet wird, ist nichts davon abhängig. Ein sehr naheliegendes Beispiel ist die forEach-Methode, bei der eine benutzerdefinierte Funktion als Argument angegeben wird, das auf jedes Element in einem Array angewendet wird, um das Array zu ändern.

Dies unterscheidet sich jedoch grundlegend von der Verwendung von "Rückruffunktionen" für asynchrone Programmierung, wie in AJAX oder node.js oder einfach beim Zuweisen von Funktionen zu Benutzerinteraktionsereignissen ( wie Mausklicks). In diesem Fall besteht die ganze Idee darin, vor dem Ausführen der benutzerdefinierten Funktionalität auf das Auftreten eines bedingten Ereignisses zu warten. Dies ist bei Benutzerinteraktionen offensichtlich, aber auch bei der Ein-/Ausgabe (Eingabe/Ausgabe) wichtig. Prozesse, die Zeit in Anspruch nehmen können, z. B. das Lesen von Dateien von der Festplatte. Hier ist der Begriff "Rückruf" am offensichtlichsten. Sobald ein E/A-Prozess gestartet wurde (z. B. die Abfrage, ob eine Datei von der Festplatte gelesen oder von einem Server zurückgegeben werden soll) Daten aus einer http-Anfrage) Ein asynchrones Programm wartet nicht auf die Fertigstellung, sondern kann nur mit den nächsten geplanten Aufgaben fortfahren Antworten Sie mit der benutzerdefinierten Funktionalität, nachdem Sie benachrichtigt wurden, dass die Lesedatei oder die HTTP-Anforderung abgeschlossen ist (oder fehlgeschlagen ist) und die Daten für die CU verfügbar sind stom Funktionalität. Es ist so, als würde man ein Unternehmen am Telefon anrufen und seine "Rückruf" -Nummer hinterlassen, damit sie Sie anrufen können, wenn jemand verfügbar ist, um mit Ihnen in Kontakt zu treten. Das ist besser, als in der Warteschlange zu bleiben, wenn man weiß, wie lange es dauert und nicht in der Lage ist, sich anderen Angelegenheiten zu widmen.

Die asynchrone Verwendung beinhaltet inhärent ein Mittel zum Abhören des gewünschten Ereignisses (z. B. des Abschlusses des E/A-Prozesses), so dass die benutzerdefinierte "Rückruf" -Funktionalität ausgeführt wird, wenn es auftritt (und nur wenn es auftritt). Im offensichtlichen Beispiel AJAX) wird, wenn die Daten tatsächlich vom Server eingehen, die "Rückruffunktion" ausgelöst, um diese Daten zum Ändern des DOM zu verwenden und daher das Browserfenster in diesem Ausmaß neu zu zeichnen.

Um es zusammenzufassen. Einige Leute verwenden das Wort "Rückruf", um auf jede Art von benutzerdefinierter Funktionalität zu verweisen, die als Argument in eine vorhandene Funktion eingefügt werden kann. Zumindest für mich ist die am besten geeignete Verwendung von Word jedoch die asynchrone Verwendung der eingespeisten "Rückruffunktion", die nur beim Auftreten eines Ereignisses ausgeführt werden soll, auf dessen Benachrichtigung gewartet wird.

37
Robert Polevoi

In Nicht-Programmierer-Begriffen ist ein Rückruf ein Ausfüllen der Lücke in einem Programm.

Ein häufiger Punkt auf vielen Papierformularen ist "Person, die im Notfall angerufen werden muss". Dort ist eine leere Zeile. Sie schreiben in den Namen und die Telefonnummer einer Person. Wenn ein Notfall eintritt, wird diese Person angerufen.

  • Jeder bekommt das gleiche Formular, aber
  • Jeder kann eine andere Notrufnummer schreiben.

Das ist der Schlüssel. Sie ändern das Formular nicht (den Code, normalerweise von jemand anderem). Sie können jedoch fehlende Informationen eingeben ( Ihre Nummer).

Beispiel 1:

Rückrufe werden als benutzerdefinierte Methoden verwendet, um möglicherweise das Verhalten eines Programms zu ändern. Nehmen Sie zum Beispiel einen C-Code, der eine Funktion ausführt, aber nicht weiß, wie die Ausgabe gedruckt wird. Alles was es tun kann, ist eine Zeichenfolge zu erstellen. Wenn versucht wird, herauszufinden, was mit der Zeichenfolge geschehen soll, wird eine leere Zeile angezeigt. Aber der Programmierer hat Ihnen das Leerzeichen gegeben, in das Sie Ihren Rückruf schreiben können!

In diesem Beispiel verwenden Sie keinen Bleistift, um ein Leerzeichen auf einem Blatt Papier auszufüllen, sondern die Funktion set_print_callback(the_callback).

  • Die leere Variable im Modul/Code ist die leere Zeile,
  • set_print_callback Ist der Bleistift,
  • und the_callback sind Ihre Informationen, die Sie eingeben.

Sie haben jetzt diese leere Zeile im Programm ausgefüllt. Immer wenn eine Ausgabe gedruckt werden muss, wird diese leere Zeile angezeigt und die dortigen Anweisungen befolgt (dh die von Ihnen dort eingegebenen Funktionen aufgerufen). über eine Netzwerkverbindung oder eine beliebige Kombination davon. Sie haben die Lücke mit dem ausgefüllt, was Sie tun möchten.

Beispiel 2:

Wenn Ihnen mitgeteilt wird, dass Sie eine Notrufnummer anrufen müssen, lesen Sie, was auf dem Papierformular steht, und rufen Sie dann die gelesene Nummer an. Wenn diese Zeile leer ist, wird nichts unternommen.

Die GUI-Programmierung funktioniert ähnlich. Wenn eine Schaltfläche angeklickt wird, muss das Programm herausfinden, was als Nächstes zu tun ist. Es geht und sucht den Rückruf. Dieser Rückruf befindet sich zufällig in einem leeren Feld mit der Bezeichnung "Was tun, wenn auf Button1 geklickt wird?"

Die meisten IDEs füllen das Feld automatisch aus (schreiben Sie die grundlegende Methode), wenn Sie dazu aufgefordert werden (z. B. button1_clicked). Dieses Leerzeichen kann jedoch jede Methode haben , die Sie verdammt noch mal gut finden . Sie können die Methode run_computations Oder butter_the_biscuits Aufrufen, solange Sie den Namen dieses Rückrufs in das entsprechende Leerzeichen setzen. Sie können "555-555-1212" in die Notrufnummer eingeben. Das ergibt wenig Sinn, ist aber zulässig.


Letzte Anmerkung: Diese leere Zeile, die Sie mit dem Rückruf ausfüllen? Es kann nach Belieben gelöscht und neu geschrieben werden. (ob Sie sollten oder nicht, ist eine andere Frage, aber das ist ein Teil ihrer Macht)

26
JoeyG

Johny, der Programmierer, braucht einen Hefter, also geht er zur Bürobedarfsabteilung und bittet um einen. Nachdem er das Anfrageformular ausgefüllt hat, kann er entweder dort stehen und warten, bis der Angestellte sich im Lager nach dem Hefter umsieht (wie bei einem Blockierfunktionsaufruf) ) oder mach in der Zwischenzeit etwas anderes.

da dies normalerweise einige Zeit in Anspruch nimmt, fügt Johny dem Anfrageformular eine Notiz hinzu, in der er ihn anruft, wenn der Hefter zur Abholung bereit ist. In der Zwischenzeit kann er also auf seinem Schreibtisch ein Nickerchen machen.

21
tovmeod

Immer besser mit einem Beispiel zu beginnen :).

Nehmen wir an, Sie haben zwei Module A und B.

Sie möchten, dass Modul A benachrichtigt wird, wenn ein Ereignis/eine Bedingung in Modul B eintritt. Modul B hat jedoch keine Ahnung von Ihrem Modul A. Alles, was es weiß, ist eine Adresse für eine bestimmte Funktion (von Modul A) ) über einen Funktionszeiger, der ihm vom Modul A zur Verfügung gestellt wird.

Alles, was B jetzt tun muss, ist "Rückruf" in Modul A, wenn ein bestimmtes Ereignis/eine bestimmte Bedingung unter Verwendung des Funktionszeigers auftritt. A kann innerhalb der Callback-Funktion weiterverarbeiten.

*) Ein klarer Vorteil hierbei ist, dass Sie alles über Modul A von Modul B abstrahieren. Modul B muss sich nicht darum kümmern, wer/was Modul A ist.

20
Gargi Srinivas

Stellen Sie sich vor, Sie brauchen eine Funktion, die 10 zum Quadrat zurückgibt, und schreiben eine Funktion:

function tenSquared() {return 10*10;}

Später brauchen Sie 9 im Quadrat, damit Sie eine andere Funktion schreiben können:

function nineSquared() {return 9*9;}

Schließlich werden Sie all diese durch eine generische Funktion ersetzen:

function square(x) {return x*x;}

Genau dasselbe gilt für Rückrufe. Sie haben eine Funktion, die etwas tut, und wenn Sie fertig sind, rufen Sie doA auf:

function computeA(){
    ...
    doA(result);
}

Später möchten Sie, dass die exakt gleiche Funktion doB aufruft, anstatt die gesamte Funktion zu duplizieren:

function computeB(){
    ...
    doB(result);
}

Oder Sie übergeben eine Rückruffunktion als Variable und müssen die Funktion nur einmal haben:

function compute(callback){
    ...
    callback(result);
}

Dann müssen Sie nur noch compute (doA) und compute (doB) aufrufen.

Abgesehen von der Vereinfachung des Codes teilt er Ihnen mit, dass der asynchrone Code abgeschlossen ist, indem er Ihre beliebige Funktion nach Abschluss aufruft, ähnlich wie wenn Sie jemanden am Telefon anrufen und eine Rückrufnummer hinterlassen.

18
Brian Nickel

Du fühlst dich krank, also gehst du zum Arzt. Er untersucht Sie und stellt fest, dass Sie Medikamente brauchen. Er verschreibt einige Medikamente und ruft das Rezept in Ihre örtliche Apotheke. Du gehst nach Hause. Später ruft Ihre Apotheke an, um Ihnen mitzuteilen, dass Ihr Rezept fertig ist. Du gehst und holst es ab.

11
effigy

Es müssen zwei Punkte erklärt werden: Zum einen die Funktionsweise eines Rückrufs (Weitergabe einer Funktion, die ohne Kenntnis ihres Kontexts aufgerufen werden kann) und zum anderen, wofür sie verwendet wird (asynchrone Verarbeitung von Ereignissen).

Die Analogie des Wartens auf das Eintreffen eines Pakets, die von anderen Antworten verwendet wurde, ist eine gute Erklärung für beides. In einem Computerprogramm weisen Sie den Computer an, ein Paket zu erwarten. Normalerweise würde es jetzt dort sitzen und warten (und nichts anderes tun), bis das Paket eintrifft, möglicherweise auf unbestimmte Zeit, wenn es nie eintrifft. Für den Menschen klingt dies albern, aber ohne weitere Maßnahmen ist dies für einen Computer völlig selbstverständlich.

Jetzt wäre der Rückruf die Klingel an Ihrer Haustür. Sie bieten dem Paketdienst eine Möglichkeit, Sie über die Ankunft des Pakets zu informieren, ohne dass dieser wissen muss, wo (auch wenn) Sie sich im Haus befinden oder wie die Klingel funktioniert. (Einige "Glocken" senden beispielsweise tatsächlich einen Anruf.) Da Sie eine "Rückruffunktion" bereitgestellt haben, die jederzeit außerhalb des Kontexts "aufgerufen" werden kann, können Sie jetzt aufhören, auf der Veranda zu sitzen und "mit dem Anruf umgehen" event "(der Paketankunft), wann immer es Zeit ist.

10
Hanno Fietz

Rückrufe lassen sich am einfachsten in Bezug auf die Telefonanlage beschreiben. Ein Funktionsaufruf entspricht dem Anrufen einer Person an einem Telefon, dem Stellen einer Frage, dem Abrufen einer Antwort und dem Auflegen. Durch Hinzufügen eines Rückrufs wird die Analogie dahingehend geändert, dass nach Wenn Sie ihr eine Frage stellen, geben Sie auch Ihren Namen und Ihre Nummer an, damit sie Sie mit der Antwort zurückrufen kann. - Paul Jakubik, "Callback-Implementierungen in C++"

6
DejanLekic

Stellen Sie sich vor, eine Freundin verlässt Ihr Haus und sagt zu ihr: "Rufen Sie mich an, wenn Sie nach Hause kommen, damit ich weiß, dass Sie sicher angekommen sind." das ist (wörtlich) ein Rückruf. Das ist eine Rückruffunktion, unabhängig von der Sprache. Sie möchten, dass eine Prozedur die Kontrolle an Sie zurückgibt, wenn eine Aufgabe erledigt ist, und Sie geben ihr eine Funktion, mit der Sie zurückgerufen werden können.

In Python zum Beispiel

grabDBValue( (lambda x: passValueToGUIWindow(x) ))

grabDBValue kann so geschrieben werden, dass nur ein Wert aus einer Datenbank abgerufen und angegeben wird, was mit dem Wert tatsächlich geschehen soll, sodass eine Funktion akzeptiert wird. Sie wissen nicht, wann oder ob grabDBValue zurückkehren wird, aber wenn/wann, wissen Sie, was Sie möchten. Hier übergebe ich eine anonyme Funktion (oder lambda), die den Wert an ein GUI-Fenster sendet. Ich könnte das Verhalten des Programms leicht ändern, indem ich dies tue:

grabDBValue( (lambda x: passToLogger(x) ))

Rückrufe funktionieren gut in Sprachen, in denen Funktionen erste Klasse Werte sind, genau wie die üblichen Ganzzahlen, Zeichenketten, Booleschen Werte usw. In C können Sie eine Funktion "übergeben", indem Sie einen Zeiger darauf übergeben und der Anrufer kann das benutzen; In Java fragt der Aufrufer nach einer statischen Klasse eines bestimmten Typs mit einem bestimmten Methodennamen, da es außerhalb der Klassen keine Funktionen ("Methoden") gibt. und in den meisten anderen dynamischen Sprachen können Sie einfach eine Funktion mit einfacher Syntax übergeben.

Protip:

In Sprachen mit lexikalischer Bereich (wie Schema oder Perl) können Sie einen Trick wie diesen ziehen:

my $var = 2;
my $val = someCallerBackFunction(sub callback { return $var * 3; });
# Perlistas note: I know the sub doesn't need a name, this is for illustration

$val in diesem Fall wird 6 weil der Callback Zugriff auf die Variablen hat, die in der lexikalischen Umgebung deklariert wurden, in der er definiert wurde. Lexikalischer Geltungsbereich und anonyme Rückrufe sind eine leistungsstarke Kombination, die weitere Studien für den unerfahrenen Programmierer rechtfertigt.

6
gatlin

Stellen wir uns vor, Sie würden mir eine potenziell langwierige Aufgabe geben: Nennen Sie die Namen der ersten fünf Personen, denen Sie begegnen. Dies kann Tage dauern, wenn ich mich in einem dünn besiedelten Gebiet befinde. Du bist nicht wirklich daran interessiert, auf deinen Händen zu sitzen, während ich herumlaufe, also sagst du: "Wenn du die Liste hast, ruf mich in meinem Handy an und lies sie mir vor. Hier ist die Nummer.".

Sie haben mir eine Rückrufreferenz gegeben - eine Funktion, die ich ausführen soll, um die weitere Verarbeitung abzugeben.

In JavaScript könnte es ungefähr so ​​aussehen:

var lottoNumbers = [];
var callback = function(theNames) {
  for (var i=0; i<theNames.length; i++) {
    lottoNumbers.Push(theNames[i].length);
  }
};

db.executeQuery("SELECT name " +
                "FROM tblEveryOneInTheWholeWorld " +
                "ORDER BY proximity DESC " +
                "LIMIT 5", callback);

while (lottoNumbers.length < 5) {
  playGolf();
}
playLotto(lottoNumbers);

Dies könnte wahrscheinlich in vielerlei Hinsicht verbessert werden. Beispielsweise könnten Sie einen zweiten Rückruf veranlassen: Wenn dies länger als eine Stunde dauert, rufen Sie das rote Telefon an und teilen Sie der Person, die antwortet, mit, dass Ihre Zeit abgelaufen ist.

6
steamer25

Ohne Rückruf weder andere spezielle Programmierressourcen (wie Threading und andere), ein Programm ist genau eine Folge von Befehlen, die nacheinander abgearbeitet werden und auch mit einer Art "dynamischem Verhalten" bestimmt unter bestimmten Bedingungen alle möglichen Szenarien müssen vorher programmiert werden.

Wenn wir also einem Programm ein echtes dynamisches Verhalten verleihen müssen, können wir Callback verwenden. Mit Callback können Sie durch Parameter ein Programm anweisen, ein anderes Programm mit zuvor definierten Parametern aufzurufen, und einige Ergebnisse erwarten ( dies ist die Vertrags- oder Vorgangsunterschrift ), damit diese Ergebnisse von einem Drittanbieterprogramm erstellt/verarbeitet werden können, das bisher nicht bekannt war.

Diese Technik ist die Grundlage des Polymorphismus, der auf Programme, Funktionen, Objekte und alle anderen von Computern ausgeführten Codeeinheiten angewendet wird.

Die menschliche Welt, die als Beispiel für einen Rückruf dient, wird in Nizza erklärt, wenn Sie einen Job machen. Nehmen wir an, Sie sind ein Maler (. Hier sind Sie das Hauptprogramm, das malt ) und rufen Sie Ihren Kunden manchmal an, um ihn zu bitten, das Ergebnis Ihrer Arbeit zu bestätigen. Er entscheidet dann, ob das Bild gut ist (. Ihr Kunde ist das Programm eines Drittanbieters ).

Im obigen Beispiel sind Sie ein Maler und "delegieren" die Aufgabe, das Ergebnis zu genehmigen, das Bild ist der Parameter, und jeder neue Kunde (die zurückgerufene "Funktion") ändert das Ergebnis Ihrer Arbeit, indem er entscheidet, was er will Über das Bild ( Die von den Kunden getroffene Entscheidung ist das zurückgegebene Ergebnis der "Rückruffunktion" ).

Ich hoffe, diese Erklärung kann nützlich sein.

6
Luciano

Sie haben Code, den Sie ausführen möchten. Wenn Sie es anrufen, warten Sie normalerweise darauf, dass es fertig ist, bevor Sie weitermachen (was dazu führen kann, dass Ihre App grau wird/eine Rotationszeit für einen Cursor erzeugt).

Eine alternative Methode besteht darin, diesen Code parallel auszuführen und Ihre eigene Arbeit fortzusetzen. Aber was ist, wenn Ihr ursprünglicher Code abhängig von der Antwort des aufgerufenen Codes unterschiedliche Aufgaben ausführen muss? In diesem Fall können Sie den Namen/Speicherort des Codes eingeben, den Sie aufrufen möchten, wenn der Vorgang abgeschlossen ist. Dies ist ein "Rückruf".

Normaler Code: Nach Informationen fragen-> Informationen verarbeiten-> Verarbeitungsergebnisse verarbeiten-> Weitere Aktionen ausführen.

Mit Rückrufen: Nach Informationen fragen-> Informationen verarbeiten-> Weitere Aktionen ausführen. Und zu einem späteren Zeitpunkt-> Beschäftige dich mit den Ergebnissen der Verarbeitung.

6
Andrew Ducker

Ein Callback ist eine Funktion, die von einer zweiten Funktion aufgerufen wird. Diese zweite Funktion weiß nicht im Voraus, welche Funktion sie aufruft. Das Identität der Rückruffunktion wird also irgendwo gespeichert oder als Parameter an die zweite Funktion übergeben. Diese "Identität" kann abhängig von der Programmiersprache die Adresse des Rückrufs oder eine andere Art von Zeiger oder der Name der Funktion sein. Der Principal ist derselbe, wir speichern oder übergeben einige Informationen, die die Funktion eindeutig identifizieren.

Wenn die Zeit gekommen ist, kann die zweite Funktion den Rückruf aufrufen und Parameter abhängig von den Umständen zu diesem Zeitpunkt bereitstellen. Möglicherweise wird sogar der Rückruf aus einer Reihe möglicher Rückrufe ausgewählt. Die Programmiersprache muss eine Art Syntax bereitstellen, damit die zweite Funktion den Rückruf aufrufen kann, wobei sie ihre "Identität" kennt.

Dieser Mechanismus hat sehr viele Verwendungsmöglichkeiten. Mit Rückrufen kann der Designer einer Funktion diese anpassen, indem er alle bereitgestellten Rückrufe aufruft. Beispielsweise kann eine Sortierfunktion einen Rückruf als Parameter annehmen, und dieser Rückruf kann eine Funktion zum Vergleichen von zwei Elementen sein, um zu entscheiden, welches zuerst eintritt.

Übrigens, abhängig von der Programmiersprache, könnte das Wort "function" in der obigen Diskussion durch "block", "closure", "lambda" usw. ersetzt werden.

5
David Casseres

Normalerweise haben wir Variablen an Funktionen gesendet. Angenommen, Sie haben eine Aufgabe, bei der die Variable verarbeitet werden muss, bevor sie als Argument angegeben wird. Sie können den Rückruf verwenden.

function1(var1, var2) ist der übliche Weg.

Was ist, wenn var2 Verarbeitet und dann als Argument gesendet werden soll? function1(var1, function2(var2))

Dies ist eine Art von Rückruf - wobei function2 Code ausführt und eine Variable an die ursprüngliche Funktion zurückgibt.

5
Nishant

Zum Einlernen von Rückrufen müssen Sie zuerst den Zeiger einlernen. Sobald die Schüler die Idee des Zeigers auf eine Variable verstanden haben, wird die Vorstellung von Rückrufen einfacher. Angenommen, Sie verwenden C/C++, können diese Schritte ausgeführt werden.

  • Zeigen Sie Ihren Schülern zunächst, wie Sie Variablen mithilfe von Zeigern neben den normalen Variablenbezeichnern verwenden und bearbeiten.
  • Dann lehre sie, dass es Dinge gibt, die nur mit Zeigern gemacht werden können (wie das Übergeben einer Variablen als Referenz).
  • Sagen Sie ihnen dann, wie ausführbarer Code oder ausführbare Funktionen genau wie andere Daten (oder Variablen) im Speicher sind. Funktionen haben also auch Adressen oder Zeiger.
  • Zeigen Sie ihnen dann, wie Funktionen mit Funktionszeigern aufgerufen werden können, und teilen Sie ihnen mit, dass diese Rückrufe genannt werden.
  • Die Frage ist nun, warum all diese Probleme beim Aufrufen einiger Funktionen auftreten. Was ist der vorteil Wie Datenzeiger hat auch der Funktionszeiger (Callbacks) einige Vorteile gegenüber der Verwendung normaler Bezeichner.
  • Der erste ist, dass Funktionsbezeichner oder Funktionsnamen nicht als normale Daten verwendet werden können. Ich meine, Sie können keine Datenstruktur mit Funktionen erstellen (wie ein Array oder eine verknüpfte Liste von Funktionen). Mit Rückrufen können Sie jedoch ein Array oder eine verknüpfte Liste erstellen oder diese mit anderen Daten wie im Wörterbuch von Schlüssel-Wert-Paaren oder -Bäumen oder anderen Dingen verwenden. Dies ist ein starker Vorteil. Und andere Vorteile sind tatsächlich ein Kind von diesem.
  • Die häufigste Verwendung von Rückrufen wird bei der Programmierung von Ereignistreibern beobachtet. Wobei eine oder mehrere Funktionen basierend auf einem eingehenden Signal ausgeführt werden. Mit Rückrufen kann ein Wörterbuch verwaltet werden, um Signale mit Rückrufen abzubilden. Dann wird die Auflösung des Eingangssignals und die Ausführung des entsprechenden Codes viel einfacher.
  • Die zweite Verwendung von Rückrufen, die mir in den Sinn kommt, sind Funktionen höherer Ordnung. Die Funktionen, die andere Funktionen als Eingabeargumente verwenden. Und um Funktionen als Argumente zu senden, brauchen wir Rückrufe. Ein Beispiel kann eine Funktion sein, die ein Array und einen Callback annimmt. Anschließend wird der Rückruf für jedes Element des Arrays ausgeführt und die Ergebnisse in einem anderen Array zurückgegeben. Übergeben wir der Funktion einen doppelten Rückruf, erhalten wir ein Array mit doppeltem Wert. Übergeben wir einen Quadratur-Callback, erhalten wir Quadrate. Für Quadratwurzeln senden Sie einfach den entsprechenden Rückruf. Dies ist mit normalen Funktionen nicht möglich.

Es könnte noch viel mehr Dinge geben. Binden Sie die Schüler ein und sie werden es entdecken. Hoffe das hilft.

4
Gulshan

Eine metaphorische Erklärung:

Ich habe ein Paket, das ich einem Freund zustellen lassen möchte, und ich möchte auch wissen, wann mein Freund es erhält.

Also bringe ich das Paket zur Post und bitte sie, es auszuliefern. Wenn ich wissen möchte, wann mein Freund das Paket erhält, habe ich zwei Möglichkeiten:

(a) Ich kann bei der Post warten, bis sie zugestellt wird.

(b) Ich erhalte eine E-Mail, wenn sie zugestellt wird.

Option (b) ist analog zu einem Rückruf.

4
tonylo

Im Klartext ist ein Rückruf ein Versprechen. Joe, Jane, David und Samantha teilen sich eine Fahrgemeinschaft, um zu arbeiten. Joe fährt heute. Jane, David und Samantha haben zwei Möglichkeiten:

  1. Überprüfen Sie alle 5 Minuten das Fenster, um festzustellen, ob Joe nicht da ist
  2. Mach weiter, bis Joe an der Tür klingelt.

Option 1: Dies ist eher ein Polling-Beispiel, bei dem Jane in einer "Schleife" festsitzt und prüft, ob Joe draußen ist. Jane kann in der Zwischenzeit nichts anderes tun.

Option 2: Dies ist das Rückrufbeispiel. Jane sagt Joe, er soll an ihrer Tür klingeln, wenn er draußen ist. Sie gibt ihm eine "Funktion", um die Türklingel zu läuten. Joe muss nicht wissen, wie die Türklingel funktioniert oder wo sie ist, er muss nur diese Funktion aufrufen, d. H. Die Türklingel läuten, wenn er dort ist.

Rückrufe werden von "Ereignissen" gesteuert. In diesem Beispiel ist das "Ereignis" Joes Ankunft. In Ajax können Ereignisse beispielsweise "Erfolg" oder "Misserfolg" der asynchronen Anforderung sein und jeweils dieselben oder unterschiedliche Rückrufe haben.

In Bezug auf JavaScript-Anwendungen und Rückrufe. Wir müssen auch "Abschlüsse" und den Anwendungskontext verstehen. Was "dies" bedeutet, kann JavaScript-Entwickler leicht verwirren. In diesem Beispiel gibt es innerhalb der "ring_the_door_bell ()" - Methode/des Rückrufs jeder Person möglicherweise einige andere Methoden, die jede Person basierend auf ihrer Morgenroutine ausführen muss, z. "Schalte den Fernseher aus()". Wir möchten, dass "dies" auf das Objekt "Jane" oder das Objekt "David" verweist, damit jeder das einrichten kann, was er sonst noch tun muss, bevor Joe sie aufnimmt. Hier muss zum Einrichten des Rückrufs mit Joe die Methode parodiert werden, damit "this" auf das richtige Objekt verweist.

Ich hoffe, das hilft!

3
Nael El Shawwa

Ich denke, es ist eine ziemlich einfache Aufgabe zu erklären.

Beim ersten Rückruf handelt es sich nur um gewöhnliche Funktionen.
Und das weitere ist, dass wir diese Funktion (nennen wir sie A) aus einer anderen Funktion heraus aufrufen (nennen wir sie B).

Die Magie dabei ist, dass ich entscheide, welche Funktion von der Funktion von außerhalb B aufgerufen werden soll.

Zum Zeitpunkt des Schreibens der Funktion B weiß ich nicht, welche Rückruffunktion aufgerufen werden soll. Zum Zeitpunkt des Aufrufs von Funktion B fordere ich diese Funktion auch auf, Funktion A aufzurufen. Das ist alles.

3
yunzen

Was ist eine Rückruffunktion?

Die einfache Antwort auf diese erste Frage lautet, dass eine Rückruffunktion eine Funktion ist, die über einen Funktionszeiger aufgerufen wird. Wenn Sie den Zeiger (die Adresse) einer Funktion als Argument an einen anderen übergeben, wird beim Aufrufen der Funktion, auf die der Zeiger verweist, ein Rückruf gemeldet.

Rückruffunktion ist schwer zu verfolgen, aber manchmal ist es sehr nützlich. Vor allem, wenn Sie Bibliotheken entwerfen. Die Rückruffunktion ähnelt dem Auffordern eines Benutzers, Ihnen einen Funktionsnamen zu geben, und Sie rufen diese Funktion unter bestimmten Bedingungen auf.

Beispielsweise schreiben Sie einen Rückruftimer. Hier können Sie die Dauer und die aufzurufende Funktion festlegen und die Funktion wird entsprechend zurückgerufen. "Führen Sie myfunction () 5 Mal alle 10 Sekunden aus."

Sie können auch ein Funktionsverzeichnis erstellen, eine Liste mit Funktionsnamen übergeben und die Bibliothek auffordern, den entsprechenden Rückruf auszuführen. "Rückruf erfolgreich (), wenn erfolgreich, Rückruf fehlgeschlagen (), wenn fehlgeschlagen."

Schauen wir uns ein einfaches Beispiel für einen Funktionszeiger an

void cbfunc()
{
     printf("called");
}

 int main ()
 {
                   /* function pointer */ 
      void (*callback)(void); 
                   /* point to your callback function */ 
      callback=(void *)cbfunc; 
                   /* perform callback */
      callback();
      return 0; 
}

Wie übergebe ich ein Argument an die Rückruffunktion?

Beobachtet, dass der Funktionszeiger zum Implementieren des Rückrufs void * enthält, was darauf hinweist, dass er jede Art von Variable einschließlich Struktur aufnehmen kann. Daher können Sie mehrere Argumente nach Struktur übergeben.

typedef struct myst
{
     int a;
     char b[10];
}myst;

void cbfunc(myst *mt) 
{
     fprintf(stdout,"called %d %s.",mt->a,mt->b); 
}

int main() 
{
       /* func pointer */
    void (*callback)(void *);       //param
     myst m;
     m.a=10;
     strcpy(m.b,"123");       
     callback = (void*)cbfunc;    /* point to callback function */
     callback(&m);                /* perform callback and pass in the param */
     return 0;   
}
3
Sachin Mhetre

Ein Rückruf ist ein an sich selbst adressierter Briefumschlag. Wenn Sie eine Funktion aufrufen, ist das wie das Senden eines Briefes. Wenn Sie möchten, dass diese Funktion eine andere Funktion aufruft, geben Sie diese Informationen in Form einer Referenz oder Adresse an.

3
pete

„Bei der Computerprogrammierung ist ein Rückruf ein Verweis auf ausführbaren Code oder einen ausführbaren Code, der als Argument an einen anderen Code übergeben wird. Auf diese Weise kann eine untergeordnete Softwareschicht eine in einer übergeordneten Schicht definierte Unterroutine (oder Funktion) aufrufen. “- Wikipedia

Rückruf in C mit Funktionszeiger

In C wird der Rückruf mit dem Funktionszeiger implementiert. Funktionszeiger - wie der Name schon sagt, ist er ein Zeiger auf eine Funktion.

Zum Beispiel int (* ptrFunc) ();

Hier ist ptrFunc ein Zeiger auf eine Funktion, die keine Argumente akzeptiert und eine Ganzzahl zurückgibt. Vergessen Sie NICHT, die Klammer einzugeben, da der Compiler sonst annimmt, dass ptrFunc ein normaler Funktionsname ist, der nichts akzeptiert und einen Zeiger auf eine Ganzzahl zurückgibt.

Hier ist ein Code zur Demonstration des Funktionszeigers.

#include<stdio.h>
int func(int, int);
int main(void)
{
    int result1,result2;
    /* declaring a pointer to a function which takes
       two int arguments and returns an integer as result */
    int (*ptrFunc)(int,int);

    /* assigning ptrFunc to func's address */                    
    ptrFunc=func;

    /* calling func() through explicit dereference */
    result1 = (*ptrFunc)(10,20);

    /* calling func() through implicit dereference */        
    result2 = ptrFunc(10,20);            
    printf("result1 = %d result2 = %d\n",result1,result2);
    return 0;
}

int func(int x, int y)
{
    return x+y;
}

Versuchen wir nun, das Konzept von Callback in C mit dem Funktionszeiger zu verstehen.

Das vollständige Programm hat drei Dateien: callback.c, reg_callback.h und reg_callback.c.

/* callback.c */
#include<stdio.h>
#include"reg_callback.h"

/* callback function definition goes here */
void my_callback(void)
{
    printf("inside my_callback\n");
}

int main(void)
{
    /* initialize function pointer to
    my_callback */
    callback ptr_my_callback=my_callback;                        
    printf("This is a program demonstrating function callback\n");
    /* register our callback function */
    register_callback(ptr_my_callback);                          
    printf("back inside main program\n");
    return 0;
}

/* reg_callback.h */
typedef void (*callback)(void);
void register_callback(callback ptr_reg_callback);


/* reg_callback.c */
#include<stdio.h>
#include"reg_callback.h"

/* registration goes here */
void register_callback(callback ptr_reg_callback)
{
    printf("inside register_callback\n");
    /* calling our callback function my_callback */
    (*ptr_reg_callback)();                               
}

Wenn wir dieses Programm ausführen, wird die Ausgabe sein

Dies ist ein Programm, das den Funktionsrückruf innerhalb von register_callback innerhalb von my_callback innerhalb des Hauptprogramms demonstriert

Die Funktion höherer Ebene ruft eine Funktion niedrigerer Ebene als normalen Aufruf auf, und der Rückrufmechanismus ermöglicht es der Funktion niedrigerer Ebene, die Funktion höherer Ebene über einen Zeiger auf eine Rückruffunktion aufzurufen.

Rückruf in Java Using Interface

Java hat nicht das Konzept eines Funktionszeigers. Es implementiert den Callback-Mechanismus über seinen Interface-Mechanismus. Hier deklarieren wir anstelle eines Funktionszeigers ein Interface mit einer Methode, die aufgerufen wird, wenn der Angerufene seine Aufgabe beendet

Lassen Sie es mich anhand eines Beispiels demonstrieren:

Die Callback-Schnittstelle

public interface Callback
{
    public void notify(Result result);
}

Der Anrufer oder die höhere Klasse

public Class Caller implements Callback
{
Callee ce = new Callee(this); //pass self to the callee

//Other functionality
//Call the Asynctask
ce.doAsynctask();

public void notify(Result result){
//Got the result after the callee has finished the task
//Can do whatever i want with the result
}
}

Die Callee oder die Funktion der unteren Ebene

public Class Callee {
Callback cb;
Callee(Callback cb){
this.cb = cb;
}

doAsynctask(){
//do the long running task
//get the result
cb.notify(result);//after the task is completed, notify the caller
}
}

Rückruf mit EventListener-Muster

  • Listenpunkt

Dieses Muster wird verwendet, um 0 bis n Anzahl von Beobachtern/Zuhörern zu benachrichtigen, dass eine bestimmte Aufgabe beendet wurde

  • Listenpunkt

Der Unterschied zwischen dem Callback - Mechanismus und dem EventListener/Observer - Mechanismus besteht darin, dass der Angerufene im Callback den einzelnen Anrufer benachrichtigt, während der Angerufene im Eventlisener/Observer jeden benachrichtigen kann, der an diesem Ereignis interessiert ist (die Benachrichtigung kann auch an andere Stellen der Mailbox gesendet werden) Anwendung, die die Aufgabe nicht ausgelöst hat)

Lassen Sie es mich anhand eines Beispiels erklären.

Die Ereignisschnittstelle

public interface Events {

public void clickEvent();
public void longClickEvent();
}

Klassen-Widget

package com.som_itsolutions.training.Java.exampleeventlistener;

import Java.util.ArrayList;
import Java.util.Iterator;

public class Widget implements Events{

    ArrayList<OnClickEventListener> mClickEventListener = new ArrayList<OnClickEventListener>(); 
    ArrayList<OnLongClickEventListener> mLongClickEventListener = new ArrayList<OnLongClickEventListener>();

    @Override
    public void clickEvent() {
        // TODO Auto-generated method stub
        Iterator<OnClickEventListener> it = mClickEventListener.iterator();
                while(it.hasNext()){
                    OnClickEventListener li = it.next();
                    li.onClick(this);
                }   
    }
    @Override
    public void longClickEvent() {
        // TODO Auto-generated method stub
        Iterator<OnLongClickEventListener> it = mLongClickEventListener.iterator();
        while(it.hasNext()){
            OnLongClickEventListener li = it.next();
            li.onLongClick(this);
        }

    }

    public interface OnClickEventListener
    {
        public void onClick (Widget source);
    }

    public interface OnLongClickEventListener
    {
        public void onLongClick (Widget source);
    }

    public void setOnClickEventListner(OnClickEventListener li){
        mClickEventListener.add(li);
    }
    public void setOnLongClickEventListner(OnLongClickEventListener li){
        mLongClickEventListener.add(li);
    }
}

Klassenknopf

public class Button extends Widget{
private String mButtonText;
public Button (){
} 
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}

Class Checkbox

public class CheckBox extends Widget{
private boolean checked;
public CheckBox() {
checked = false;
}
public boolean isChecked(){
return (checked == true);
}
public void setCheck(boolean checked){
this.checked = checked;
}
}

Aktivitätsklasse

package com.som_itsolutions.training.Java.exampleeventlistener;

public class Activity implements Widget.OnClickEventListener
{
    public Button mButton;
    public CheckBox mCheckBox;
    private static Activity mActivityHandler;
    public static Activity getActivityHandle(){
        return mActivityHandler;
    }
    public Activity ()
    {
        mActivityHandler = this;
        mButton = new Button();
        mButton.setOnClickEventListner(this);
        mCheckBox = new CheckBox();
        mCheckBox.setOnClickEventListner(this);
        } 
    public void onClick (Widget source)
    {
        if(source == mButton){
            mButton.setButtonText("Thank you for clicking me...");
            System.out.println(((Button) mButton).getButtonText());
        }
        if(source == mCheckBox){
            if(mCheckBox.isChecked()==false){
                mCheckBox.setCheck(true);
                System.out.println("The checkbox is checked...");
            }
            else{
                mCheckBox.setCheck(false);
                System.out.println("The checkbox is not checked...");
            }       
        }
    }
    public void doSomeWork(Widget source){
        source.clickEvent();
    }   
}

Andere Klasse

public class OtherClass implements Widget.OnClickEventListener{
Button mButton;
public OtherClass(){
mButton = Activity.getActivityHandle().mButton;
mButton.setOnClickEventListner(this);//interested in the click event                        //of the button
}
@Override
public void onClick(Widget source) {
if(source == mButton){
System.out.println("Other Class has also received the event notification...");
}
}

Hauptklasse

public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Activity a = new Activity();
OtherClass o = new OtherClass();
a.doSomeWork(a.mButton);
a.doSomeWork(a.mCheckBox);
}
}

Wie Sie dem obigen Code entnehmen können, haben wir eine Schnittstelle namens events, die im Grunde alle Ereignisse auflistet, die für unsere Anwendung auftreten können. Die Widget-Klasse ist die Basisklasse für alle UI-Komponenten wie Button und Checkbox. Diese UI-Komponenten sind die Objekte, die die Ereignisse tatsächlich aus dem Framework-Code erhalten. Die Widget-Klasse implementiert die Ereignis-Schnittstelle und verfügt auch über zwei verschachtelte Schnittstellen, nämlich OnClickEventListener und OnLongClickEventListener

Diese beiden Schnittstellen sind für das Abhören von Ereignissen verantwortlich, die in von Widgets abgeleiteten UI-Komponenten wie Button oder Checkbox auftreten können. Wenn wir dieses Beispiel mit dem früheren Callback-Beispiel unter Verwendung von Java Interface) vergleichen, fungieren diese beiden Interfaces als Callback-Interface Wenn ein Ereignis in einem Widget eintritt, wird der Code der höheren Ebene (oder die Methode dieser Schnittstellen, die in dem Code der höheren Ebene implementiert ist, hier Activity) aufgerufen.

Lassen Sie mich nun den grundsätzlichen Unterschied zwischen Callback- und Eventlistener-Pattern diskutieren. Wie bereits erwähnt, kann die Callee mit Callback nur einen einzelnen Anrufer benachrichtigen. Im Fall des EventListener-Musters kann jedoch jeder andere Teil oder jede andere Klasse der Anwendung für die Ereignisse registriert werden, die auf der Schaltfläche oder im Kontrollkästchen auftreten können. Das Beispiel für diese Art von Klasse ist die OtherClass. Wenn Sie den Code der OtherClass sehen, werden Sie feststellen, dass sie sich als Listener für das ClickEvent registriert hat, das in der in der Aktivität definierten Schaltfläche auftreten kann. Interessant ist, dass diese OtherClass neben der Activity (dem Caller) auch benachrichtigt wird, wenn das Click-Ereignis auf dem Button auftritt.

Schlicht und einfach: Ein Callback ist eine Funktion, die Sie einer anderen Funktion geben, damit diese call it kann.

Normalerweise wird es aufgerufen, wenn eine Operation abgeschlossen ist. Da Sie den Rückruf erstellen, bevor Sie ihn an die andere Funktion übergeben, können Sie ihn mit Kontextinformationen von der Aufrufsite initialisieren. Aus diesem Grund wird es als Aufruf * zurück * bezeichnet - die erste Funktion ruft den Kontext auf, von dem aus sie aufgerufen wurde.

2
Andrei Vajna II

Ein Rückruf ist eine Methode, die ausgeführt werden soll, wenn eine Bedingung erfüllt ist.

Ein Beispiel aus der "realen Welt" ist ein lokaler Videospieleladen. Sie warten auf Half-Life 3. Anstatt jeden Tag in den Laden zu gehen, um zu sehen, ob das Spiel verfügbar ist, registrieren Sie Ihre E-Mail-Adresse in einer Liste, um benachrichtigt zu werden, wenn das Spiel verfügbar ist. Die E-Mail wird zu Ihrem "Rückruf" und die Bedingung, die erfüllt werden muss, ist die Verfügbarkeit des Spiels.

Ein Beispiel für "Programmierer" ist eine Webseite, auf der Sie eine Aktion ausführen möchten, wenn Sie auf eine Schaltfläche klicken. Sie registrieren eine Rückrufmethode für eine Schaltfläche und fahren mit anderen Aufgaben fort. Wenn der Benutzer auf die Schaltfläche klickt, zeigt der Browser die Liste der Rückrufe für dieses Ereignis an und ruft Ihre Methode auf.

Ein Rückruf ist eine Möglichkeit, Ereignisse asynchron zu behandeln. Sie können nie wissen, wann der Rückruf ausgeführt wird oder ob er überhaupt ausgeführt wird. Der Vorteil besteht darin, dass Ihr Programm und Ihre CPU-Zyklen frei sind, um andere Aufgaben auszuführen, während Sie auf die Antwort warten.

2
Optimist

[bearbeitet] Wenn wir zwei Funktionen haben, sagen Sie functionA und functionB , wenn functionA hängt von functionB ab.

dann rufen wir functionB als Rückruffunktion auf, was im Spring-Framework weit verbreitet ist.

callback function wikipedia example

1

Stellen Sie sich eine Methode als Aufgabe für einen Mitarbeiter vor. Eine einfache Aufgabe könnte sein:

Solve these equations:
x + 2 = y
2 * x = 3 * y

Ihr Kollege rechnet fleißig nach und gibt Ihnen folgendes Ergebnis:

x = -6
y = -4

Aber dein Kollege hat ein Problem, er versteht nicht immer Notationen wie ^, aber er versteht sie unter ihrer Beschreibung. Wie exponent. Jedes Mal, wenn er eine davon findet, erhalten Sie Folgendes zurück:

I don't understand "^"

Dies erfordert, dass Sie Ihren gesamten Befehlssatz erneut schreiben, nachdem Sie Ihrem Kollegen erklärt haben, was der Charakter bedeutet, und dass er sich zwischen den Fragen nicht immer daran erinnert. Und er hat auch Schwierigkeiten, sich an Ihre Tipps zu erinnern, z. B. fragen Sie mich einfach. Er folgt immer Ihren schriftlichen Anweisungen, so gut er kann.

Wenn Sie sich eine Lösung überlegen, fügen Sie all Ihren Anweisungen Folgendes hinzu:

If you have any questions about symbols, call me at extension 1234 and I will tell you its name.

Wenn er ein Problem hat, ruft er Sie an und fragt, anstatt Ihnen eine schlechte Antwort zu geben und den Prozess neu zu starten.

1
Guvante

Mit Callbacks können Sie Ihren eigenen Code in einen anderen Codeblock einfügen, der zu einem anderen Zeitpunkt ausgeführt werden soll. Dadurch wird das Verhalten dieses anderen Codeblocks entsprechend Ihren Anforderungen geändert oder ergänzt. Sie gewinnen Flexibilität und Anpassbarkeit, während Sie in der Lage sind, mehr wartbaren Code zu haben.

Weniger Hardcode = einfacher zu warten und zu ändern = weniger Zeit = mehr Geschäftswert = großartig.

In Javascript könnten Sie mit Underscore.js beispielsweise alle geraden Elemente in einem Array wie folgt finden:

var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]

Beispiel mit freundlicher Genehmigung von Underscore.js: http://documentcloud.github.com/underscore/#filter

1
letuboy

Rückruffunktionen:

Wir definieren ein callback function mit dem Namen callback gib ihm einen Parameter otherFunction und rufe ihn im Funktionskörper auf.

function callback(otherFunction){
    otherFunction();
}

Wenn wir die Funktion callback aufrufen, erwartet sie ein Argument vom Typ function, sodass wir es mit einer anonymen Funktion aufrufen. Es wird jedoch ein Fehler ausgegeben, wenn das Argument nicht vom Typ function ist.

callback(function(){console.log('SUCCESS!')}); 
callback(1); // error

Beispiel Pizza backen. ofen zum backen von pizzaböden mit zutaten Jetzt ist hier oven der callback function. und pizza base with ingredients ist das otherFunction.

Hinweis ist, dass verschiedene Pizzabestandteile verschiedene Pizzasorten produzieren, aber der Ofen beim backen bleibt es gleich. Das ist ein bisschen ein Job von callback function, das weiterhin Funktionen mit unterschiedlichen Funktionalitäten erwartet, um unterschiedliche benutzerdefinierte Ergebnisse zu erzielen.

0
Sagar Munjal

Dies in Bezug auf das Herunterladen einer Webseite:

Ihr Programm läuft auf einem Mobiltelefon und fordert die Webseite http://www.google.com an. Wenn Sie Ihr Programm synchron schreiben, wird die Funktion zum Herunterladen der Daten so lange ausgeführt, bis alle Daten heruntergeladen sind. Dies bedeutet, dass Ihre Benutzeroberfläche nicht aktualisiert wird und grundsätzlich eingefroren erscheint. Wenn Sie Ihr Programm mit Rückrufen schreiben, fordern Sie die Daten an und sagen "Führen Sie diese Funktion aus, wenn Sie fertig sind." Auf diese Weise kann die Benutzeroberfläche weiterhin Benutzerinteraktionen zulassen, während die Datei heruntergeladen wird. Sobald der Download der Webseite abgeschlossen ist, wird Ihre Ergebnisfunktion (Callback) aufgerufen und Sie können mit den Daten umgehen.

Grundsätzlich können Sie etwas anfordern und die Ausführung fortsetzen, während Sie auf das Ergebnis warten. Sobald das Ergebnis über eine Rückruffunktion zu Ihnen zurückkehrt, können Sie den Vorgang dort fortsetzen, wo er aufgehört hat.

0
sokket