Was ist eine Rückruffunktion?
Was ist eine Rückruffunktion?
Antworten:
Entwickler sind oft verwirrt darüber, was ein Rückruf aufgrund des Namens der verdammten Sache ist.
Eine Rückruffunktion ist eine Funktion, die:
Eine gute Möglichkeit, sich vorzustellen, wie eine Rückruffunktion funktioniert, besteht darin, dass es sich um eine Funktion handelt, die " auf der Rückseite " der Funktion aufgerufen wird, an 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 immer dann 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, wenn Sie event () aufgerufen haben:
The number you provided is: 6
I have finished printing numbers.
Die Reihenfolge der Ausgabe ist hier wichtig. Da die Rückruffunktionen anschließend aufgerufen werden, wird "Ich habe das Drucken von Nummern beendet" zuletzt und nicht zuerst gedruckt.
Rückrufe werden aufgrund ihrer Verwendung mit Zeigersprachen so genannt. Wenn Sie keine davon verwenden, arbeiten Sie nicht über den Namen "Rückruf". Verstehen Sie einfach, dass es nur ein Name ist, um eine Methode zu beschreiben, die als Argument für eine andere Methode angegeben wird, z. Die Rückruffunktion wird dann aufgerufen.
Einige Sprachen unterstützen Konstrukte, bei denen mehrere Rückruffunktionsargumente unterstützt werden, und werden basierend auf dem Abschluss der übergeordneten Funktion aufgerufen (dh ein Rückruf wird aufgerufen, wenn die übergeordnete Funktion erfolgreich abgeschlossen wurde, ein anderer wird aufgerufen, wenn die übergeordnete Funktion a auslöst spezifischer Fehler usw.).
once its parent method completes, the function which this argument represents is then called
. Wenn also die Funktion als Argument an eine andere Funktion übergeben wird, aber wie in der Mitte der Laufzeit der übergeordneten Funktion aufgerufen wird parent(cb) {dostuff1(); cb(); dostuff2()}
, wird sie nicht als callback
Funktion betrachtet?
Eine Rückruffunktion ist eine Funktion, die Sie einem anderen Code bereitstellen, damit dieser von diesem Code aufgerufen werden kann.
Warum willst du das tun? Angenommen, Sie müssen einen Dienst aufrufen. Wenn der Service sofort zurückkehrt, müssen Sie nur:
Angenommen, der Dienst wäre die factorial
Funktion. Wenn Sie den Wert von möchten 5!
, würden Sie aufrufen factorial(5)
und die folgenden Schritte würden ausgeführt:
Ihr aktueller Ausführungsort wird gespeichert (auf dem Stapel, aber das ist nicht wichtig)
Die Ausführung wird an übergeben factorial
Wenn factorial
der Vorgang abgeschlossen ist, wird das Ergebnis an einer Stelle abgelegt, an der Sie es erreichen können
Die Ausführung kehrt dorthin zurück, wo sie in [1] war.
Nehmen wir nun an, es factorial
hat sehr lange gedauert, weil Sie ihm riesige Zahlen geben und es irgendwo auf einem Supercomputer-Cluster laufen muss. Angenommen, Sie erwarten, dass es 5 Minuten dauert, bis Ihr Ergebnis zurückgegeben wird. Du könntest:
Behalten Sie Ihr Design bei und führen Sie Ihr Programm nachts aus, wenn Sie schlafen, damit Sie nicht die halbe Zeit auf den Bildschirm starren
Entwerfen Sie Ihr Programm, um andere Dinge zu tun, während factorial
es seine Sache tut
Wenn Sie die zweite Option auswählen, funktionieren Rückrufe möglicherweise für Sie.
Um ein Rückrufmuster auszunutzen, möchten Sie in der Lage sein, factorial
auf folgende Weise aufzurufen :
factorial(really_big_number, what_to_do_with_the_result)
Der zweite Parameter what_to_do_with_the_result
ist eine Funktion, an die Sie senden factorial
, in der Hoffnung, dass factorial
sie das Ergebnis vor der Rückkehr aufruft.
Ja, das bedeutet das factorial
geschrieben werden muss, um Rückrufe zu unterstützen.
Angenommen, Sie möchten einen Parameter an Ihren Rückruf übergeben können. Jetzt können Sie nicht, weil Sie es nicht nennen werden, factorial
ist. Es factorial
muss also geschrieben werden, damit Sie Ihre Parameter übergeben können, und sie werden nur an Ihren Rückruf übergeben, wenn dieser aufgerufen wird. 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ässig ist, könnte Ihr Rückruf folgendermaßen aussehen:
logIt (number, logger)
{
logger.log(number)
}
und dein Anruf factorial
wäre
factorial(42, logIt, logger)
Was ist, wenn Sie etwas zurückgeben möchten logIt
? Das kannst du nicht, weilfactorial
nicht darauf achtest.
Warum nicht? factorial
einfach zurückgeben, was Ihr Rückruf zurückgibt?
Da die Ausführung nach Abschluss an den Rückruf übergeben werden factorial
soll, sollte sie dem Anrufer eigentlich nichts zurückgeben. Und im Idealfall würde es irgendwie seine Arbeit in einem anderen Thread / Prozess / Maschine starten und sofort zurückkehren, damit Sie fortfahren können, vielleicht so etwas:
factorial(param_1, param_2, ...)
{
new factorial_worker_task(param_1, param_2, ...);
return;
}
Dies ist jetzt ein "asynchroner Aufruf". Wenn Sie ihn aufrufen, wird er sofort zurückgegeben, hat seine Aufgabe jedoch noch nicht wirklich erledigt. Sie benötigen also Mechanismen, um dies zu überprüfen und das Ergebnis zu erhalten, wenn es fertig ist, und Ihr Programm ist dabei komplexer geworden.
Übrigens mit diesem Muster die factorial_worker_task
können Sie Ihren Rückruf asynchron starten und sofort zurückkehren.
Die Antwort ist, innerhalb des Rückrufmusters zu bleiben. Wann immer du schreiben willst
a = f()
g(a)
und f
soll asynchron aufgerufen werden, schreiben Sie stattdessen
f(g)
wo g
wird als Rückruf übergeben.
Dies ändert die Flusstopologie Ihres Programms grundlegend und ist gewöhnungsbedürftig.
Ihre Programmiersprache kann Ihnen sehr helfen, indem sie Ihnen die Möglichkeit gibt, Funktionen im laufenden Betrieb zu erstellen. Im Code direkt darüber ist die Funktion g
möglicherweise so klein wie print (2*a+1)
. Wenn Ihre Sprache erfordert, dass Sie dies als separate Funktion mit einem völlig unnötigen Namen und einer völlig unnötigen Signatur definieren, wird Ihr Leben unangenehm, wenn Sie dieses Muster häufig verwenden.
Wenn Sie andererseits mit Ihrer Sprache Lambdas erstellen können, sind Sie in einer viel besseren Verfassung. Sie werden dann am Ende so etwas schreiben
f( func(a) { print(2*a+1); })
das ist so viel schöner.
Wie würden Sie die Rückruffunktion übergeben factorial
? Nun, Sie können es auf verschiedene Arten tun.
Wenn die aufgerufene Funktion im selben Prozess ausgeführt wird, können Sie einen Funktionszeiger übergeben
Oder vielleicht möchten Sie ein Wörterbuch von fn name --> fn ptr
in Ihrem Programm pflegen. In diesem Fall könnten Sie den Namen übergeben
Vielleicht erlaubt Ihnen Ihre Sprache, die Funktion direkt zu definieren, möglich als Lambda! Intern wird eine Art Objekt erstellt und ein Zeiger übergeben, aber darüber müssen Sie sich keine Sorgen machen.
Möglicherweise wird die von Ihnen aufgerufene Funktion auf einem völlig separaten Computer ausgeführt, und Sie rufen sie über ein Netzwerkprotokoll wie HTTP auf. Sie können Ihren Rückruf als HTTP-aufrufbare Funktion verfügbar machen und seine URL übergeben.
Du hast die Idee.
In dieser Web-Ära, in die wir eingetreten sind, werden die von uns aufgerufenen Dienste häufig über das Netzwerk bereitgestellt. Wir haben oft keine Kontrolle über diese Dienste, dh wir haben sie nicht geschrieben, wir pflegen sie nicht, wir können nicht sicherstellen, dass sie verfügbar sind oder wie sie funktionieren.
Wir können jedoch nicht erwarten, dass unsere Programme blockiert werden, während wir darauf warten, dass diese Dienste antworten. In diesem Bewusstsein entwerfen die Dienstanbieter häufig APIs nach dem Rückrufmuster.
JavaScript unterstützt Rückrufe sehr gut, zB bei Lambdas und Closures. In der JavaScript-Welt gibt es viele Aktivitäten, sowohl im Browser als auch auf dem Server. Es werden sogar JavaScript-Plattformen für Mobilgeräte entwickelt.
Im weiteren Verlauf werden immer mehr von uns asynchronen Code schreiben, für den dieses Verständnis von entscheidender Bedeutung sein wird.
Beachten Sie, dass Rückruf ein Wort ist.
Die Wikipedia-Rückrufseite erklärt es sehr gut.
Zitat aus der Wikipedia-Seite:
Bei der Computerprogrammierung ist ein Rückruf eine Referenz 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 Unterroutine (oder Funktion) aufrufen, die in einer übergeordneten Ebene definiert ist.
Eine Rückruffunktion sollte aufgerufen werden, wenn eine bestimmte Bedingung erfüllt ist. Anstatt sofort aufgerufen zu werden, wird die Rückruffunktion zu einem bestimmten Zeitpunkt in der Zukunft aufgerufen.
In der Regel wird es verwendet, wenn eine Aufgabe gestartet wird, die asynchron beendet wird (dh einige Zeit nach der Rückkehr der aufrufenden Funktion beendet wird).
Für eine Funktion zum Anfordern einer Webseite muss der Aufrufer möglicherweise eine Rückruffunktion bereitstellen, die aufgerufen wird, wenn der Download der Webseite abgeschlossen ist.
"...when a condition is met"
aber ich dachte, Rückrufe werden aufgerufen, wenn die übergeordnete Funktion die Ausführung beendet hat und sind nicht abhängig von Bedingungen (?).
Rückrufe lassen sich am einfachsten anhand des Telefonsystems beschreiben. Ein Funktionsaufruf ist analog dazu, jemanden am Telefon anzurufen, ihr eine Frage zu stellen, eine Antwort zu erhalten und aufzulegen. Durch Hinzufügen eines Rückrufs wird die Analogie geändert, sodass Sie ihr nach dem Stellen einer Frage auch Ihren Namen und Ihre Nummer geben, damit sie Sie mit der Antwort zurückrufen kann.
- Paul Jakubik, "Callback-Implementierungen in C ++"
Ich glaube, dieser "Rückruf" -Jargon wurde an vielen Stellen fälschlicherweise verwendet. Meine Definition wäre so etwas wie:
Eine Rückruffunktion ist eine Funktion, die Sie an jemanden übergeben und ihn zu einem bestimmten Zeitpunkt aufrufen lassen.
Ich denke, die Leute lesen gerade den ersten Satz der Wiki-Definition:
Ein Rückruf ist eine Referenz auf ausführbaren Code oder einen ausführbaren Code, der als Argument an anderen Code übergeben wird.
Ich habe mit vielen APIs gearbeitet, siehe verschiedene schlechte Beispiele. Viele Leute neigen dazu, einen Funktionszeiger (einen Verweis auf ausführbaren Code) oder anonyme Funktionen (einen Teil des ausführbaren Codes) als "Rückruf" zu bezeichnen. Wenn es sich nur um Funktionen handelt, warum benötigen Sie dafür einen anderen Namen?
Tatsächlich zeigt nur der zweite Satz in der Wiki-Definition die Unterschiede zwischen einer Rückruffunktion und einer normalen Funktion:
Dies ermöglicht einer untergeordneten Softwareschicht, eine in einer übergeordneten Ebene definierte Unterroutine (oder Funktion) aufzurufen.
Der Unterschied besteht also darin, wer die Funktion übergeben wird und wie Ihre übergebene Funktion aufgerufen wird. Wenn Sie nur eine Funktion definieren und an eine andere Funktion übergeben und direkt in diesem Funktionskörper aufrufen, nennen Sie sie keinen Rückruf. Die Definition besagt, dass Ihre übergebene Funktion von der Funktion "unterer Ebene" aufgerufen wird.
Ich hoffe, die Leute können aufhören, dieses Wort in einem mehrdeutigen Kontext zu verwenden. Es kann den Leuten nicht helfen, besser und nur schlechter zu verstehen.
Lassen Sie es uns einfach halten. Was ist eine Rückruffunktion?
Beispiel durch Parabel und Analogie
Ich habe eine Sekretärin. Jeden Tag bitte ich sie: (i) die ausgehende Post der Firma bei der Post abzugeben, und nachdem sie das getan hat, Folgendes zu tun: (ii) jede Aufgabe, die ich für sie auf eine dieser Haftnotizen geschrieben habe .
Was ist nun die Aufgabe auf dem Notizzettel? Die Aufgabe variiert von Tag zu Tag.
Angenommen, an diesem Tag muss sie einige Dokumente ausdrucken. Also schreibe ich das auf die Notiz und stecke sie zusammen mit der ausgehenden Post, die sie posten muss, auf ihren Schreibtisch.
Zusammenfassend:
Die Rückruffunktion ist die zweite Aufgabe: das Ausdrucken dieser Dokumente. Weil es erledigt ist, nachdem die Post abgegeben wurde, und weil ihr die Haftnotiz, die sie zum Drucken des Dokuments auffordert, zusammen mit der Post, die sie senden muss, gegeben wird.
Lassen Sie uns dies jetzt mit dem Programmiervokabular verknüpfen
Das ist alles was es ist. Nichts mehr. Ich hoffe, das hat es für Sie geklärt - und wenn nicht, schreiben Sie einen Kommentar und ich werde mein Bestes tun, um dies zu klären.
Dadurch klingen Rückrufe wie return-Anweisungen am Ende von Methoden.
Ich bin mir nicht sicher, ob sie das sind.
Ich denke, Rückrufe sind tatsächlich ein Aufruf einer Funktion, als Folge einer anderen Funktion, die aufgerufen und abgeschlossen wird.
Ich denke auch, dass Rückrufe dazu gedacht sind, die ursprüngliche Anrufung in einer Art "Hey! Das Ding, nach dem Sie gefragt haben? Ich habe es getan - ich dachte nur, ich würde Sie wissen lassen - zurück zu Ihnen" zu adressieren.
Was ist ein Rückruf ?
Was ist eine Rückruffunktion ?
otherFunction
als Parameter an eine andere Funktion übergeben wird (nennen wir diese andere Funktion ), und die Rückruffunktion wird innerhalb von aufgerufen (oder ausgeführt) otherFunction
. function action(x, y, callback) {
return callback(x, y);
}
function multiplication(x, y) {
return x * y;
}
function addition(x, y) {
return x + y;
}
alert(action(10, 10, multiplication)); // output: 100
alert(action(10, 10, addition)); // output: 20
In SOA ermöglicht der Rückruf den Plugin-Modulen den Zugriff auf Dienste aus dem Container / der Umgebung.
Analogie: Rückrufe. Asynchron. Nicht blockierendes
Beispiel aus der Praxis für Rückruf
Call After wäre ein besserer Name als der blöde Name Callback . Wenn oder wenn eine Bedingung innerhalb einer Funktion erfüllt ist, rufen Sie eine andere Funktion auf, die Call After- Funktion, die als Argument empfangen wurde.
Anstatt eine innere Funktion innerhalb einer Funktion fest zu codieren, schreibt man eine Funktion, um eine bereits geschriebene Call After- Funktion als Argument zu akzeptieren . Der Call After wird möglicherweise basierend auf Statusänderungen aufgerufen, die vom Code in der Funktion erkannt werden, die das Argument empfängt.
Eine Rückruffunktion ist eine Funktion, die Sie für eine vorhandene Funktion / Methode angeben. Sie wird aufgerufen, wenn eine Aktion abgeschlossen ist, zusätzliche Verarbeitung erfordert usw.
In Javascript oder genauer gesagt in jQuery können Sie beispielsweise ein Rückrufargument angeben, das aufgerufen werden soll, wenn eine Animation beendet ist.
In PHP preg_replace_callback()
können Sie mit dieser Funktion eine Funktion bereitstellen, die aufgerufen wird, wenn der reguläre Ausdruck übereinstimmt, und die Zeichenfolge (n) übergeben, die als Argumente übereinstimmen.
schau dir das Bild an :)
Das Hauptprogramm ruft die Bibliotheksfunktion (möglicherweise auch eine Funktion auf Systemebene) mit dem Namen der Rückruffunktion 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 Rückruffunktion während der Ausführung auf.
Die einfache Antwort auf diese 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 eine andere übergeben, wird beim Aufrufen der Funktion, auf die dieser Zeiger verweist, darauf hingewiesen, dass ein Rückruf erfolgt
Angenommen, wir haben eine Funktion, sort(int *arraytobesorted,void (*algorithmchosen)(void))
in der ein Funktionszeiger als Argument akzeptiert werden kann, der zu einem bestimmten Zeitpunkt in sort()
der Implementierung verwendet werden kann. Dann wird hier der Code, der vom Funktionszeiger adressiert algorithmchosen
wird, als Rückruffunktion aufgerufen .
Und der Vorteil ist, dass wir jeden Algorithmus wählen können wie:
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, mit dem Polymorphismus in der objektorientierten Programmierung erreicht wird
„In der Computerprogrammierung ist ein Rückruf eine Referenz 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 Unterroutine (oder Funktion) aufrufen, die in einer übergeordneten Ebene definiert ist. “ - Wikipedia
Rückruf in C mit Funktionszeiger
In C wird der Rückruf mit dem Funktionszeiger implementiert. Funktionszeiger - ist, wie der Name schon sagt, 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, in Klammern zu setzen, sonst geht der Compiler davon aus, dass ptrFunc ein normaler Funktionsname ist, der nichts nimmt 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 des Rückrufs 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 sein
Dies ist ein Programm, das den Funktionsrückruf in register_callback in my_callback zurück im Hauptprogramm demonstriert
Die Funktion der höheren Schicht ruft eine Funktion der unteren Schicht als normalen Aufruf auf, und der Rückrufmechanismus 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 Schnittstelle
Java hat nicht das Konzept eines Funktionszeigers. Es implementiert den Rückrufmechanismus über seinen Schnittstellenmechanismus. Hier deklarieren wir anstelle eines Funktionszeigers eine Schnittstelle mit einer Methode, die aufgerufen wird, wenn der Angerufene seine Aufgabe beendet
Lassen Sie es mich anhand eines Beispiels demonstrieren:
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
Dieses Muster wird verwendet, um 0 bis n Anzahlen von Beobachtern / Zuhörern zu benachrichtigen, dass eine bestimmte Aufgabe beendet wurde
Der Unterschied zwischen dem Rückrufmechanismus und dem EventListener / Observer-Mechanismus besteht darin, dass der Angerufene beim Rückruf den einzelnen Anrufer benachrichtigt, während der Angerufene bei Eventlisener / Observer jeden benachrichtigen kann, der an diesem Ereignis interessiert ist (die Benachrichtigung kann an einige andere Teile des 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);
}
}
Klassenschaltfläche
public class Button extends Widget{
private String mButtonText;
public Button (){
}
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}
Klassen-Kontrollkästchen
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 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, Checkbox. Diese UI-Komponenten sind die Objekte, die die Ereignisse tatsächlich vom Framework-Code empfangen. Die Widget-Klasse implementiert die Ereignisschnittstelle 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 auf den vom Widget abgeleiteten UI-Komponenten wie Button oder Checkbox auftreten können. Wenn wir dieses Beispiel mit dem früheren Callback-Beispiel unter Verwendung der Java-Schnittstelle vergleichen, fungieren diese beiden Schnittstellen als Callback-Schnittstelle. Der übergeordnete Code (Here Activity) implementiert diese beiden Schnittstellen. Und wenn ein Ereignis in einem Widget auftritt, wird der Code auf höherer Ebene (oder die Methode dieser Schnittstellen, die im Code auf höherer Ebene implementiert ist, der hier Aktivität ist) aufgerufen.
Lassen Sie mich nun den grundlegenden Unterschied zwischen Callback- und Eventlistener-Muster diskutieren. Wie bereits erwähnt, kann der Callee mit Callback nur einen einzigen Anrufer benachrichtigen. Im Fall 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 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 neben der Aktivität (dem Anrufer) diese andere Klasse auch benachrichtigt wird, wenn das Klickereignis auf der Schaltfläche auftritt.
Eine Rückruffunktion ist eine Funktion, die Sie (als Referenz oder Zeiger) an eine bestimmte Funktion oder ein bestimmtes Objekt übergeben. Diese Funktion oder dieses Objekt ruft diese Funktion zu einem späteren Zeitpunkt, möglicherweise mehrmals, für einen beliebigen Zweck zurück:
...
Die Beschreibung eines Rückrufs als eine Funktion, die am Ende einer anderen Funktion oder Aufgabe aufgerufen wird, ist daher zu einfach (auch wenn es sich um einen häufigen Anwendungsfall handelt).
Ein Rückruf ist eine Idee, eine Funktion als Parameter an eine andere Funktion zu übergeben und diese nach Abschluss des Prozesses aufzurufen.
Wenn Sie das Konzept des Rückrufs durch großartige Antworten erhalten, empfehle ich Ihnen, den Hintergrund seiner Idee zu lernen.
"Warum haben sie (Informatiker) einen Rückruf entwickelt?" Möglicherweise stellen Sie ein Problem fest, das blockiert (insbesondere das Blockieren der Benutzeroberfläche). Ein Rückruf ist nicht die einzige Lösung dafür. Es gibt viele andere Lösungen (z. B. Thread, Futures, Versprechen ...).
Ein wichtiger Anwendungsbereich besteht darin, dass Sie eine Ihrer Funktionen als Handle (dh als Rückruf) registrieren und dann eine Nachricht senden / eine Funktion aufrufen, um Arbeiten oder Verarbeitungen durchzuführen. Nachdem die Verarbeitung abgeschlossen ist, ruft die aufgerufene Funktion unsere registrierte Funktion auf (dh der Rückruf erfolgt jetzt), was anzeigt, dass die Verarbeitung abgeschlossen ist.
Dieser Wikipedia-Link erklärt sich recht gut grafisch.
Eine Rückruffunktion, auch als Funktion höherer Ordnung bekannt, ist eine Funktion, die als Parameter an eine andere Funktion übergeben wird, und die Rückruffunktion wird innerhalb der übergeordneten Funktion aufgerufen (oder ausgeführt).
$("#button_1").click(function() {
alert("button 1 Clicked");
});
Hier haben wir eine Funktion als Parameter an die click-Methode übergeben. Und die click-Methode ruft die Rückruffunktion auf (oder führt sie aus), die wir an sie übergeben haben.
Rückruffunktion Eine Funktion, die als Argument an eine andere Funktion übergeben wurde.
function test_function(){
alert("Hello world");
}
setTimeout(test_function, 2000);
Hinweis: Im obigen Beispiel wird test_function als Argument für die Funktion setTimeout verwendet.