it-swarm.com.de

Was ist eine Rückruffunktion?

Was ist eine Rückruffunktion?

583
paul

Entwickler sind oft verwirrt darüber, was ein Rückruf ist, und zwar wegen des Namens der verdammten Sache.

Eine Rückruffunktion ist eine Funktion, die:

  • erreichbar durch eine andere Funktion, und
  • wird nach der ersten Funktion aufgerufen, wenn die erste Funktion abgeschlossen ist

Eine schöne Vorstellung davon, wie eine Rückruffunktion funktioniert, ist, dass es sich um eine Funktion handelt, die " an der Rückseite " der Funktion aufgerufen wird, in die sie übergeben wird.

Vielleicht wäre ein besserer Name eine "call after" - Funktion. 

Dieses Konstrukt ist sehr nützlich für asynchrones Verhalten, bei dem eine Aktivität stattfinden soll, wenn ein vorheriges Ereignis abgeschlossen ist.

Pseudocode:

// A function which accepts another function as an argument
// (and will automatically invoke that function when it completes - note that there is no explicit call to callbackFunction)
funct printANumber(int number, funct callbackFunction) {
    printout("The number you provided is: " + number);
}

// a function which we will use in a driver function as a callback function
funct printFinishMessage() {
    printout("I have finished printing numbers.");
}

// Driver method
funct event() {
   printANumber(6, printFinishMessage);
}

Ergebnis beim Aufruf von event ():

The number you provided is: 6
I have finished printing numbers.

Die Reihenfolge der Ausgabe ist hier wichtig. Da Callback-Funktionen danach aufgerufen werden, wird "Ich habe fertig gedruckt" zuletzt gedruckt, nicht zuerst. 

Callbacks werden aufgrund ihrer Verwendung mit Zeigersprachen so genannt. Wenn Sie keine davon verwenden, sollten Sie sich nicht um den Namen "Rückruf" kümmern. Verstehen Sie einfach, dass es sich nur um einen Namen handelt, um eine Methode zu beschreiben, die als Argument für eine andere Methode angegeben wird, z. B. wenn die übergeordnete Methode aufgerufen wird (unabhängig von der jeweiligen Bedingung, z. B. einem Klick auf eine Schaltfläche, einem Timer-Häkchen usw.) und der zugehörige Methodentext. Die Callback-Funktion wird dann aufgerufen.

Einige Sprachen unterstützen Konstrukte, bei denen mehrere Rückmeldungsfunktionsargumente unterstützt werden, und sie werden abhängig davon aufgerufen, wie die übergeordnete Funktion ausgeführt wird (dh, ein Callback wird aufgerufen, wenn die übergeordnete Funktion erfolgreich abgeschlossen wurde. Eine andere wird aufgerufen, wenn die übergeordnete Funktion ein auslöst.) bestimmter Fehler usw.).

582
8bitjunkie

Undurchsichtige Definition

Eine Rückruffunktion ist eine Funktion, die Sie für einen anderen Code bereitstellen, damit dieser von diesem Code aufgerufen werden kann.

Gedachtes Beispiel

Warum möchtest du das tun? Nehmen wir an, es gibt einen Dienst, den Sie aufrufen müssen. Wenn der Dienst sofort zurückkehrt, können Sie:

  1. Nennen
  2. Warten Sie auf das Ergebnis
  3. Fahren Sie fort, sobald das Ergebnis eingeht

Angenommen, der Dienst war die Funktion factorial. Wenn Sie den Wert von 5! wünschen, würden Sie factorial(5) aufrufen, und die folgenden Schritte würden ausgeführt:

  1. Ihr aktueller Ausführungsort wird gespeichert (auf dem Stapel, aber das ist nicht wichtig)

  2. Ausführung wird an factorial übergeben

  3. Wenn factorial abgeschlossen ist, wird das Ergebnis an einem beliebigen Ort abgelegt

  4. Hinrichtung kommt dahin zurück, wo es war in [1]

Nehmen wir jetzt an, dass factorial sehr lange gedauert hat, weil Sie sehr viele Zahlen geben und es irgendwo auf einem Supercomputing-Cluster laufen muss. Nehmen wir an, Sie erwarten, dass es 5 Minuten dauern wird, um Ihr Ergebnis zurückzugeben. Du könntest:

  1. Behalten Sie Ihr Design und führen Sie Ihr Programm nachts im Schlaf aus, damit Sie nicht die halbe Zeit auf den Bildschirm starren

  2. Entwerfen Sie Ihr Programm, um andere Dinge zu tun, während factorial seine Sache tut

Wenn Sie sich für die zweite Option entscheiden, funktionieren Rückrufe möglicherweise für Sie.

End-to-End-Design

Um ein Rückrufmuster auszunutzen, möchten Sie factorial folgendermaßen aufrufen:

factorial(really_big_number, what_to_do_with_the_result)

Der zweite Parameter, what_to_do_with_the_result, ist eine Funktion, die Sie zusammen mit factorial senden, in der Hoffnung, dass factorial das Ergebnis vor dem Zurückkehren aufruft. 

Ja, das bedeutet, dass factorial zur Unterstützung von Callbacks geschrieben worden sein muss.

Angenommen, Sie möchten einen Parameter an Ihren Callback übergeben können. Jetzt können Sie nicht, weil Sie es nicht nennen werden, factorial ist. Daher muss factorial geschrieben werden, damit Sie Ihre Parameter übergeben können, und diese werden beim Aufruf einfach an den Rückruf übergeben. Es könnte so aussehen:

factorial (number, callback, params)
{
    result = number!   // i can make up operators in my pseudocode
    callback (result, params)
}

Nun, da factorial dieses Muster zulässt, könnte Ihr Rückruf so aussehen:

logIt (number, logger)
{
    logger.log(number)
}

und Ihr Aufruf an factorial wäre 

factorial(42, logIt, logger)

Was ist, wenn Sie etwas von logIt zurückgeben möchten? Nun, das geht nicht, denn factorial achtet nicht darauf.

Warum kann factorial nicht einfach nur zurückgeben, was Ihr Rückruf zurückgibt?

Nicht blockierend machen

Da die Ausführung an den Callback übergeben werden soll, wenn factorial beendet ist, sollte sie wirklich nichts an ihren Aufrufer zurückgeben. Und im Idealfall würde es seine Arbeit irgendwie in einem anderen Thread/Prozess/Computer starten und sofort zurückkehren, damit Sie fortfahren können, vielleicht so etwas wie dieses:

factorial(param_1, param_2, ...)
{
    new factorial_worker_task(param_1, param_2, ...);
    return;
}

Dies ist jetzt ein "asynchroner Aufruf", dh wenn Sie ihn aufrufen, wird er sofort zurückgegeben, hat seine Aufgabe jedoch noch nicht wirklich erledigt. Sie benötigen also Mechanismen, um das zu überprüfen und das Ergebnis zu erhalten, wenn es fertig ist und Ihr Programm im Prozess komplexer geworden ist. 

Übrigens kann der factorial_worker_task mit diesem Muster Ihren Callback asynchron starten und sofort zurückkehren.

Also, was machst du?

Die Antwort ist, innerhalb des Rückrufmusters zu bleiben. Wann immer du schreiben willst

a = f()
g(a)

und f soll asynchron aufgerufen werden, stattdessen schreiben Sie

f(g)

dabei wird g als Rückruf übergeben. 

Dies ändert die Flusstopologie Ihres Programms grundlegend und ist gewöhnungsbedürftig. 

Ihre Programmiersprache kann Ihnen sehr helfen, indem Sie die Möglichkeit haben, Funktionen schnell zu erstellen. In dem Code direkt oben könnte die Funktion g so klein wie print (2*a+1) sein. Wenn Ihre Sprache es erfordert, dass Sie diese Funktion als separate Funktion definieren, deren Name und Signatur völlig unnötig sind, wird Ihr Leben unangenehm, wenn Sie dieses Muster häufig verwenden. 

Wenn Sie andererseits in Ihrer Sprache das Erstellen von Lambdas zulassen, sind Sie in viel besserer Verfassung. Am Ende schreiben Sie so etwas wie

f( func(a) { print(2*a+1); })

das ist so viel schöner.

So übergeben Sie den Rückruf

Wie würden Sie die Rückruffunktion an factorial übergeben? Nun, Sie könnten es auf verschiedene Arten tun. 

  1. Wenn die aufgerufene Funktion in demselben Prozess ausgeführt wird, können Sie einen Funktionszeiger übergeben

  2. Oder möchten Sie vielleicht ein Wörterbuch mit fn name --> fn ptr in Ihrem Programm verwalten, in welchem ​​Fall Sie den Namen übergeben können

  3. Vielleicht erlaubt Ihnen Ihre Sprache die Definition der Funktion an Ort und Stelle, als Lambda möglich! Intern wird ein Objekt erstellt und ein Zeiger übergeben, aber darüber müssen Sie sich keine Sorgen machen.

  4. Möglicherweise wird die von Ihnen aufgerufene Funktion auf einer völlig separaten Maschine ausgeführt, und Sie rufen sie mit einem Netzwerkprotokoll wie HTTP auf. Sie könnten Ihren Rückruf als von HTTP aufrufbare Funktion bereitstellen und dessen URL übergeben.

Du hast die Idee.Der jüngste Anstieg von Rückrufen.

In diesem Web-Zeitalter, in das wir eingetreten sind, werden die von uns in Anspruch genommenen Dienste häufig über das Netzwerk ausgeführt. Wir haben oft keine Kontrolle über diese Dienste, d. H. Wir haben sie nicht geschrieben, wir behalten sie nicht bei, wir können nicht garantieren, dass sie in Betrieb sind oder wie sie funktionieren.

Wir können jedoch nicht erwarten, dass unsere Programme blockieren, während wir auf die Antwort dieser Dienste warten. Da dies bekannt ist, entwerfen die Dienstanbieter häufig APIs unter Verwendung des Rückrufmusters.

JavaScript unterstützt Rückrufe sehr gut, z. mit Lambdas und Verschlüssen. In der JavaScript-Welt gibt es viel Aktivität, sowohl im Browser als auch auf dem Server. Es gibt sogar JavaScript-Plattformen, die für Mobilgeräte entwickelt werden.

Im weiteren Verlauf werden immer mehr von uns asynchronen Code schreiben, für den dieses Verständnis unerlässlich ist.

As we move forward, more and more of us will be writing asynchronous code, for which this understanding will be essential.

195

Beachten Sie, dass der Rückruf ein Wort ist.

Die Wikipedia-Rückrufseite erklärt das sehr gut.

Zitat aus der Wikipedia-Seite:

Bei der Computerprogrammierung ist ein Rückruf ein Verweis auf ausführbaren Code oder einen ausführbaren Code, der als Argument an anderen Code übergeben wird. Dadurch kann eine untergeordnete Softwareschicht eine in einer übergeordneten Schicht definierte Subroutine (oder Funktion) aufrufen.

87
danio

Eine Laienantwort wäre, dass es sich um eine Funktion handelt, die nicht von Ihnen, sondern vom Benutzer oder vom Browser aufgerufen wird, nachdem ein bestimmtes Ereignis aufgetreten ist oder nachdem ein Code verarbeitet wurde.

40
NateH

Eine Callback-Funktion sollte aufgerufen werden, wenn eine bestimmte Bedingung erfüllt ist. Die Callback-Funktion wird nicht sofort aufgerufen, sondern zu einem bestimmten Zeitpunkt in der Zukunft.

Normalerweise wird es verwendet, wenn eine Task gestartet wird, die asynchron beendet wird (dh einige Zeit nach der Rückkehr der aufrufenden Funktion endet).

Für eine Funktion zum Anfordern einer Webseite kann es beispielsweise erforderlich sein, dass der Aufrufer eine Rückruffunktion bereitstellt, die aufgerufen wird, wenn die Webseite vollständig heruntergeladen wurde.

37
Thomas Bratt

Ich glaube, dass dieses "Callback" -Jargon an vielen Stellen versehentlich verwendet wurde. Meine Definition wäre ungefähr so:

Eine Rückruffunktion ist eine Funktion, die Sie an jemanden weitergeben und sie nennen es irgendwann.

Ich denke, die Leute haben gerade den ersten Satz der Wiki-Definition gelesen:

ein Rückruf ist ein Verweis auf ausführbaren Code oder ein Stück von ausführbarer Code, der als Argument an anderen Code übergeben wird.

Ich habe mit vielen APIs gearbeitet, siehe verschiedene schlechte Beispiele. Viele Leute nennen einen Funktionszeiger (einen Verweis auf ausführbaren Code) oder anonyme Funktionen (ein ausführbarer Code) "Rückruf". Wenn es sich nur um Funktionen handelt, warum brauchen Sie einen anderen Namen dafür?

Tatsächlich zeigt nur der zweite Satz in der Wiki-Definition die Unterschiede zwischen einer Rückruffunktion und einer normalen Funktion:

Dadurch kann eine untergeordnete Softwareschicht eine in einer übergeordneten Schicht definierte Unterroutine (oder Funktion) aufrufen.

der Unterschied ist also, wer Sie die Funktion übergeben und wie Ihre übergebene Funktion aufgerufen wird. Wenn Sie nur eine Funktion definieren und an eine andere Funktion übergeben und sie direkt in diesem Funktionskörper aufgerufen haben, rufen Sie sie nicht als Rückruf auf. Die Definition besagt, dass Ihre übergebene Funktion von der "Lower-Level" -Funktion aufgerufen wird.

Ich hoffe, die Menschen können dieses Wort in einem mehrdeutigen Kontext nicht mehr verwenden, es kann den Menschen nicht helfen, besser nur schlechter zu verstehen.

34
Zane XY

Rückrufe lassen sich am einfachsten in Bezug auf das Telefonsystem beschreiben. Ein Funktionsaufruf ist vergleichbar mit dem Anrufen einer Person über ein Telefon, dem Stellen einer Frage, dem Erhalten einer Antwort und dem Auflegen. Wenn Sie einen Rückruf hinzufügen, ändert sich die Analogie, so dass Sie ihr nach der Frage auch Ihren Namen und Ihre Nummer geben, damit sie Sie mit der Antwort zurückrufen kann.  

- Paul Jakubik, "Callback-Implementierungen in C++"

28
DejanLekic

Lass es uns einfach halten. Was ist eine Rückruffunktion?

Beispiel durch Gleichnis und Analogie

Ich habe eine Sekretärin. Ich fordere sie jeden Tag auf: (i) die Postausgänge der Firma bei der Post abzugeben, und after sie hat das getan, um: (ii) welche Aufgabe ich für sie an einem erledigt habe von diesen Haftnotizen

Was ist nun die Aufgabe auf dem Zettel? Die Aufgabe variiert von Tag zu Tag.

Angenommen, an diesem Tag muss ich einige Dokumente ausdrucken. Also schreibe ich das auf die Haftnotiz und stecke sie zusammen mit der ausgehenden Post, die sie veröffentlichen muss, auf ihren Schreibtisch.

In Summe:

  1. zuerst muss sie die Post abstellen und 
  2. unmittelbar danach das erledigt ist, muss sie einige Dokumente ausdrucken.

Die Rückruffunktion ist die zweite Aufgabe: Drucken dieser Dokumente. Weil dies erledigt wird, nachdem die Post abgelegt wurde, und auch, weil ihr die Haftnotiz mit der Aufforderung zum Ausdrucken des Dokuments zusammen mit der Post, die sie senden muss, übergeben wird.

Lassen Sie uns dies jetzt mit dem Programmiervokabular verknüpfen

  • Der Methodenname lautet in diesem Fall: DropOffMail. 
  • Und die Rückruffunktion lautet: PrintOffDocuments. Das PrintOffDocuments ist die Rückruffunktion, da die Sekretärin dies nur nach dem Ausführen von DropOffMail tun soll.
  • Ich würde also "PrintOffDocuments" als "Argument" an die DropOffMail-Methode übergeben. Dies ist ein wichtiger Punkt.

Das ist alles was es ist. Nichts mehr. Ich hoffe, das hat es für dich geklärt - und wenn nicht, schreibe einen Kommentar und ich werde mein Bestes geben, um zu klären.

26
BKSpurgeon

Dadurch klingen Callbacks am Ende von Methoden wie Rückgabeanweisungen.

Ich bin mir nicht sicher, was das ist.

Ich denke, Callbacks sind eigentlich ein Aufruf an eine Funktion, als Folge davon, dass eine andere Funktion aufgerufen und ausgeführt wird.

Ich denke auch, dass Callbacks dazu gedacht sind, sich mit der ursprünglichen Anrufung zu befassen, in einer Art "Hey! Dieses Ding, nach dem Sie gefragt haben? Ich habe es getan - ich dachte, ich würde Sie wissen lassen - zurück zu Ihnen".

16
Mauritico

Eine Rückruffunktion ist eine Funktion, die Sie für eine vorhandene Funktion/Methode angeben. Diese Funktion wird aufgerufen, wenn eine Aktion abgeschlossen ist und zusätzliche Verarbeitung erforderlich ist.

In Javascript, oder genauer in jQuery, können Sie beispielsweise ein Callback-Argument angeben, das aufgerufen wird, wenn eine Animation abgeschlossen ist.

In PHP können Sie mit der Funktion preg_replace_callback() eine Funktion bereitstellen, die aufgerufen wird, wenn der reguläre Ausdruck gefunden wird. Dabei werden die als Argumente übereinstimmenden Zeichenfolgen übergeben.

16
alex

Call After wäre ein besserer Name als der blöde Name, Callback . Wenn oder wenn die Bedingung innerhalb einer Funktion erfüllt ist, rufen Sie eine andere Funktion auf, die Call After - Funktion, die als Argument empfangen wird. 

Anstatt eine innere Funktion innerhalb einer Funktion hart zu codieren, schreibt man eine Funktion, um eine bereits geschriebene Call After - Funktion als Argument zu akzeptieren. Das Call After wird möglicherweise basierend auf Statusänderungen aufgerufen, die durch Code in der Funktion ermittelt wurden, die das Argument empfängt.

14
Smack MacDougal

schau dir das Bild an :)this is how it works

Das Hauptprogramm ruft die Bibliotheksfunktion (möglicherweise auch auf Systemebene) mit dem Callback-Funktionsnamen auf. Diese Rückruffunktion kann auf mehrere Arten implementiert werden. Das Hauptprogramm wählt je nach Anforderung einen Rückruf. 

Schließlich ruft die Bibliotheksfunktion die Callback-Funktion während der Ausführung auf.

7
user1103138

Was ist Rückruf?

  • Im Allgemeinen wird ein Anruf getätigt, um einen Anruf zurückzugeben, den jemand erhalten hat.
  • Bei der Berechnung ist ein Rückruf ein ausführbarer Code, der als Argument an anderen Code übergeben wird. Wenn die Funktion mit ihrer Arbeit erledigt ist (oder wenn ein Ereignis aufgetreten ist), ruft sie Ihre Rückruffunktion (es ruft Sie zurück - daher der Name) - Funktion ab. 

Was ist eine Rückruffunktion?

  • eine Rückruffunktion ist wie ein Diener, der seinen Master nach Beendigung einer Aufgabe zurückruft.
  • eine Callback-Funktion ist eine Funktion, die an eine andere Funktion übergeben wird (nennen wir diese andere Funktion otherFunction) als Parameter. Die Callback-Funktion wird innerhalb der otherFunction aufgerufen (oder ausgeführt). 

    funktionsaktion (x, y, Rückruf) { Callback zurückgeben (x, y); }

    funktionsmultiplikation (x, y) { Rückgabe x * y; }

    funktionsaddition (x, y) { return x + y; }

    alarm (Aktion (10, 10, Multiplikation)); // Ausgabe: 100

    alarm (Aktion (10, 10, Zusatz)); // Ausgabe: 20

In SOA ermöglicht Callback den Plugin-Modulen den Zugriff auf Dienste aus dem Container/der Umgebung.

Analogie: Rückrufe. Asynchron. Nicht blockierend
Praxisbeispiel für Rückruf

6
Premraj

Die einfache Antwort auf diese Frage ist, dass eine Rückruffunktion eine Funktion ist, die über einen Funktionszeiger aufgerufen wird. Wenn Sie den Zeiger (Adresse) einer Funktion als Argument an ein anderes übergeben, wird bei Aufruf dieses Zeigers auf die Funktion, auf die er verweist, ein Rückruf durchgeführt

6
Zain Ali

Nehmen wir an, wir haben eine Funktion sort(int *arraytobesorted,void (*algorithmchosen)(void)), in der ein Funktionszeiger als Argument akzeptiert werden kann, der irgendwann in der Implementierung von sort() verwendet werden kann. Dann wird hier der Code, der vom Funktionszeiger algorithmchosen angesprochen wird, als Callback-Funktion aufgerufen.

Der Vorteil ist, dass wir einen beliebigen Algorithmus wählen können:

  1.    algorithmchosen = bubblesort
  2.    algorithmchosen = heapsort
  3.    algorithmchosen = mergesort   ...

Welche wurden beispielsweise mit dem Prototyp implementiert:

  1.   `void bubblesort(void)`
  2.   `void heapsort(void)`
  3.   `void mergesort(void)`   ...

Dies ist ein Konzept, das zum Erreichen von Polymorphismus in der objektorientierten Programmierung verwendet wird

5
Neeraj

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

Rückruf in C mit Funktionszeiger

In C wird der Rückruf mithilfe des Funktionszeigers implementiert. Funktionszeiger - wie der Name schon sagt, ist ein Zeiger auf eine Funktion.

Zum Beispiel: int (* ptrFunc) ();

PtrFunc ist hier ein Zeiger auf eine Funktion, die keine Argumente akzeptiert und eine Ganzzahl zurückgibt. Vergessen Sie NICHT, in Klammern einzufügen, andernfalls nimmt der Compiler an, dass ptrFunc ein normaler Funktionsname ist, der nichts braucht und einen Zeiger auf eine Ganzzahl zurückgibt.

Hier ist etwas Code, um den Funktionszeiger zu demonstrieren.

#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 mithilfe des Funktionszeigers zu verstehen.

Das vollständige Programm enthält 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 erfolgen

Dies ist ein Programm, das die Funktion callback In register_callback In my_callback Im Hauptprogramm zeigt

Die Funktion der höheren Schicht ruft eine Funktion der unteren Schicht als normalen Aufruf auf, und der Callback-Mechanismus ermöglicht es der Funktion der unteren Schicht, die Funktion der höheren Schicht über einen Zeiger auf eine Rückruffunktion aufzurufen.

Rückruf in Java über die Benutzeroberfläche

Java verfügt nicht über das Konzept des Funktionszeigers Es implementiert den Callback-Mechanismus über seinen Schnittstellenmechanismus Statt eines Funktionszeigers deklarieren wir ein Interface mit einer Methode, die aufgerufen wird, wenn der Angreifer seine Aufgabe beendet

Lassen Sie mich das an einem Beispiel zeigen:

Die Rückrufschnittstelle

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 untere Schichtfunktion

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 Nummern der Beobachter/Listener darüber zu informieren, dass eine bestimmte Aufgabe abgeschlossen ist

  • Listenpunkt

Der Unterschied zwischen dem Callback-Mechanismus und dem EventListener/Observer-Mechanismus besteht darin, dass der Angerufene beim Rückruf den einzelnen Anrufer benachrichtigt, wohingegen der Angerufene bei Eventlisener/Observer jeden benachrichtigen kann, der an diesem Ereignis interessiert ist (die Benachrichtigung kann an andere Teile des Anrufbeantworters gehen Anwendung, die die Aufgabe nicht ausgelöst hat)

Lassen Sie mich das an einem Beispiel erklären.

Die Ereignisoberfläche

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

Klassentaste

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

Klassen-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

paket 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 Wesentlichen alle Ereignisse aufführt, 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 empfangen. Die Widget-Klasse implementiert die Events-Schnittstelle und verfügt außerdem über zwei verschachtelte Schnittstellen, nämlich OnClickEventListener und OnLongClickEventListener

Diese beiden Schnittstellen sind für das Abhören von Ereignissen verantwortlich, die in von Widget abgeleiteten UI-Komponenten wie Button oder Checkbox auftreten können. Wenn wir dieses Beispiel mit dem früheren Callback-Beispiel mit Java-Schnittstelle vergleichen, fungieren diese beiden Schnittstellen als Callback-Schnittstelle. Der Code auf höherer Ebene (Here Activity) implementiert diese beiden Schnittstellen. Immer wenn ein Ereignis bei einem Widget auftritt, wird der Code der höheren Ebene (oder die Methode dieser Schnittstellen, die im Code der höheren Ebene, hier Aktivität, implementiert ist) aufgerufen.

Lassen Sie mich nun den grundlegenden Unterschied zwischen dem Callback- und dem Eventlistener-Muster besprechen. Wie bereits erwähnt, kann Calle nur einen einzelnen Anrufer benachrichtigen. Im Falle eines EventListener-Musters kann sich jedoch jeder andere Teil oder jede andere Klasse der Anwendung für die Ereignisse registrieren, die auf der Schaltfläche oder dem Ankreuzfeld auftreten können. Das Beispiel dieser Klasse ist die OtherClass. Wenn Sie den Code der OtherClass sehen, werden Sie feststellen, dass sie sich selbst als Listener für das ClickEvent registriert hat, das in der in der Aktivität definierten Schaltfläche auftreten kann. Interessanter Teil ist, dass diese OtherClass neben der Aktivität (dem Aufrufer) auch benachrichtigt wird, wenn das Klickereignis auf der Schaltfläche auftritt. 

Ein Rückruf ist die Idee, eine Funktion als Parameter an eine andere Funktion zu übergeben und diese nach Abschluss des Prozesses aufrufen zu lassen.

Wenn Sie das Konzept des Rückrufs durch die oben genannten tollen Antworten erhalten, empfehle ich Ihnen, den Hintergrund der Idee zu kennen.

"Warum haben sie (Informatiker) einen Rückruf entwickelt?" Möglicherweise tritt ein Problem auf, das blockiert (insbesondere die Blockierung der Benutzeroberfläche), und Callback ist nicht die einzige Lösung dafür. Es gibt viele andere Lösungen (zum Beispiel: Thread, Futures, Versprechen ...).

1
山本燿司

Eine Callback-Funktion, auch als Funktion höherer Ordnung bezeichnet, ist eine Funktion, die als Parameter an eine andere Funktion übergeben wird, und die Callback-Funktion wird innerhalb der übergeordneten Funktion aufgerufen (oder ausgeführt).

$("#button_1").click(function() {
  alert("button 1 Clicked");
});

Hier haben wir der Click-Methode eine Funktion als Parameter übergeben. Die click-Methode ruft die Callback-Funktion auf (oder führt sie aus), die wir an sie übergeben haben.

1
ChiragK

Callback-Funktion Eine Funktion, die als Argument an eine andere Funktion übergeben wurde.

function test_function(){       
 alert("Hello world");  
} 

setTimeout(test_function, 2000);

Hinweis: In obigem Beispiel wird test_function als Argument für die Funktion setTimeout verwendet.

1
Garvin

Ein wichtiger Verwendungsbereich ist, dass Sie eine Ihrer Funktionen als Handle registrieren (d. H. Einen Rückruf) und dann eine Nachricht senden/eine Funktion aufrufen, um Arbeit oder Verarbeitung auszuführen. Nachdem die Verarbeitung abgeschlossen ist, ruft die aufgerufene Funktion nun unsere registrierte Funktion auf (d. H., Jetzt ist der Rückruf erfolgt), wodurch angezeigt wird, dass die Verarbeitung abgeschlossen ist. 
Dieser wikipedia-Link erklärt sich recht gut. 

1
Chintan Parikh

Eine Rückruffunktion ist eine Funktion, die Sie (als Referenz oder Zeiger) an eine bestimmte Funktion oder ein Objekt übergeben. Diese Funktion oder dieses Objekt ruft diese Funktion zu einem beliebigen Zeitpunkt zu einem beliebigen Zeitpunkt auf, möglicherweise mehrmals: 

  • das Ende einer Aufgabe benachrichtigen
  • anfordern eines Vergleichs zwischen zwei Elementen (wie in c qsort ())
  • berichtsfortschritt eines Prozesses
  • ereignisse benachrichtigen
  • delegieren der Instanziierung eines Objekts
  • delegieren der Malerei eines Bereichs

...

Das Beschreiben eines Rückrufs als Funktion, die am Ende einer anderen Funktion oder Aufgabe aufgerufen wird, ist daher zu stark vereinfacht (auch wenn dies ein häufiger Anwendungsfall ist).

0
XouDo