Co to jest funkcja oddzwaniania?
Co to jest funkcja oddzwaniania?
Odpowiedzi:
Deweloperzy często są zdezorientowani tym, czym jest oddzwanianie z powodu nazwy cholernej rzeczy.
Funkcja oddzwaniania to funkcja, która jest:
Dobrym sposobem wyobrażenia sobie, jak działa funkcja wywołania zwrotnego jest to, że jest to funkcja, która jest „ wywoływana z tyłu” ” funkcji, do której jest przekazywana.
Może lepszą nazwą byłoby „połączenie po” funkcja .
Ta konstrukcja jest bardzo przydatna w przypadku zachowania asynchronicznego, w którym chcemy, aby działanie miało miejsce po zakończeniu poprzedniego zdarzenia.
Pseudo kod:
// 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);
}
Wynik, jeśli wywołałeś event ():
The number you provided is: 6
I have finished printing numbers.
Ważna jest tutaj kolejność danych wyjściowych. Ponieważ funkcje wywołania zwrotnego są wywoływane później, „Skończyłem drukować numery” jest drukowane jako ostatnie, a nie pierwsze.
Oddzwonienia są nazywane ze względu na ich użycie w językach wskaźników. Jeśli nie używasz żadnego z nich, nie pracuj nad nazwą „callback”. Po prostu zrozum, że jest to tylko nazwa opisująca metodę podaną jako argument do innej metody, na przykład, gdy wywoływana jest metoda nadrzędna (niezależnie od warunków, takich jak kliknięcie przycisku, znacznik czasowy itp.), A jej treść kończy się, następnie wywoływana jest funkcja zwrotna.
Niektóre języki obsługują konstrukcje, w których obsługiwanych jest wiele argumentów funkcji wywołania zwrotnego, i są wywoływane na podstawie sposobu wykonania funkcji nadrzędnej (tj. Jedno wywołanie zwrotne jest wywoływane w przypadku pomyślnego zakończenia funkcji nadrzędnej, a inne w przypadku, gdy funkcja nadrzędna generuje konkretny błąd itp.).
once its parent method completes, the function which this argument represents is then called
. Więc jeśli funkcja jest przekazywana do innej funkcji jako argument, ale wywoływana ze środka środowiska uruchomieniowego funkcji nadrzędnej, tak jak parent(cb) {dostuff1(); cb(); dostuff2()}
wtedy, nie jest uważana za callback
funkcję?
Funkcja oddzwaniania to funkcja udostępniana w innym fragmencie kodu, umożliwiająca wywołanie go przez ten kod.
Dlaczego chcesz to zrobić? Powiedzmy, że istnieje usługa, którą musisz wywołać. Jeśli usługa natychmiast powróci, po prostu:
Załóżmy na przykład, że usługa była factorial
funkcją. Gdy chcesz tę wartość 5!
, możesz wywołać factorial(5)
, a następują następujące kroki:
Bieżąca lokalizacja wykonania jest zapisywana (na stosie, ale to nie jest ważne)
Egzekucja jest przekazywana do factorial
Po factorial
zakończeniu umieszcza wynik w miejscu, w którym można się do niego dostać
Egzekucja wraca do miejsca, w którym była [1]
Załóżmy teraz, że factorial
zajęło to naprawdę dużo czasu, ponieważ podajesz jej ogromne liczby i musi on działać gdzieś w jakimś klastrze superkomputerów. Załóżmy, że oczekujesz 5 minut na zwrócenie wyniku. Mógłbyś:
Zachowaj swój projekt i uruchom program w nocy, gdy śpisz, abyś nie patrzył na ekran przez pół czasu
Zaprojektuj swój program do robienia innych rzeczy, podczas gdy factorial
on robi swoje
Jeśli wybierzesz drugą opcję, oddzwanianie może działać.
Aby wykorzystać wzorzec wywołania zwrotnego, chcesz móc wywoływać factorial
w następujący sposób:
factorial(really_big_number, what_to_do_with_the_result)
Drugi parametr, what_to_do_with_the_result
to funkcja, do której wysyłasz factorial
, w nadziei, że factorial
wywoła go na podstawie wyniku przed powrotem.
Tak, oznacza to, że factorial
należy napisać, aby obsługiwać połączenia zwrotne.
Załóżmy teraz, że chcesz przekazać parametr do wywołania zwrotnego. Teraz nie możesz, bo nie będziesz tak nazywać, factorial
jest. Trzeba więc factorial
napisać, aby umożliwić przekazanie parametrów, a on po prostu przekaże je do oddzwaniania, gdy je wywoła. Może to wyglądać tak:
factorial (number, callback, params)
{
result = number! // i can make up operators in my pseudocode
callback (result, params)
}
Teraz, gdy factorial
pozwala na to wzorzec, Twoje wywołanie zwrotne może wyglądać następująco:
logIt (number, logger)
{
logger.log(number)
}
i twoje wezwanie factorial
byłoby
factorial(42, logIt, logger)
Co jeśli chcesz coś zwrócić logIt
? Nie możesz, bo factorial
nie zwracasz na to uwagi.
Dlaczego nie możesz factorial
po prostu zwrócić tego, co zwraca Twoje połączenie zwrotne?
Ponieważ wykonanie ma zostać przekazane do oddzwaniania, gdy factorial
jest zakończone, tak naprawdę nie powinno ono zwracać niczego swojemu rozmówcy. Idealnie byłoby, gdyby w jakiś sposób uruchomił swoją pracę w innym wątku / procesie / maszynie i natychmiast powrócił, abyś mógł kontynuować, być może coś takiego:
factorial(param_1, param_2, ...)
{
new factorial_worker_task(param_1, param_2, ...);
return;
}
Jest to teraz „wywołanie asynchroniczne”, co oznacza, że po wywołaniu natychmiast wraca, ale tak naprawdę jeszcze nie wykonał swojej pracy. Potrzebujesz więc mechanizmów, aby to sprawdzić i uzyskać wynik po zakończeniu, a Twój program stał się bardziej skomplikowany.
Nawiasem mówiąc, przy użyciu tego wzorca factorial_worker_task
można asynchronicznie uruchomić oddzwonienie i natychmiast wrócić.
Odpowiedzią jest pozostanie w ramach wzorca oddzwaniania. Kiedykolwiek chcesz pisać
a = f()
g(a)
i f
ma być wywoływany asynchronicznie, zamiast tego napiszesz
f(g)
gdzie g
jest przekazywany jako oddzwonienie.
To zasadniczo zmienia topologię przepływu twojego programu i wymaga trochę czasu, aby się przyzwyczaić.
Twój język programowania może ci bardzo pomóc, umożliwiając tworzenie funkcji w locie. W powyższym kodzie funkcja g
może być tak mała jak print (2*a+1)
. Jeśli twój język wymaga zdefiniowania go jako osobnej funkcji z całkowicie niepotrzebną nazwą i podpisem, wówczas twoje życie stanie się nieprzyjemne, jeśli będziesz często używać tego wzorca.
Jeśli natomiast Twój język pozwala ci tworzyć lambdy, to jesteś w znacznie lepszej formie. Potem skończysz pisać coś w stylu
f( func(a) { print(2*a+1); })
co jest o wiele ładniejsze.
Jak przekazałbyś funkcję oddzwaniania factorial
? Cóż, możesz to zrobić na wiele sposobów.
Jeśli wywoływana funkcja działa w tym samym procesie, można przekazać wskaźnik funkcji
A może chcesz zachować słownik fn name --> fn ptr
w swoim programie, w którym to przypadku możesz podać nazwę
Być może twój język pozwala zdefiniować funkcję w miejscu, możliwą jako lambda! Wewnętrznie tworzy jakiś obiekt i przekazuje wskaźnik, ale nie musisz się tym martwić.
Być może funkcja, którą wywołujesz, działa na całkowicie oddzielnym komputerze i wywołujesz ją za pomocą protokołu sieciowego, takiego jak HTTP. Możesz ujawnić swoje wywołanie zwrotne jako funkcję wywoływaną przez HTTP i przekazać jego adres URL.
Masz pomysł.
W erze internetowej, w którą weszliśmy, usługi, które wywołujemy, są często realizowane przez sieć. Często nie mamy żadnej kontroli nad tymi usługami, tj. Nie napisaliśmy ich, nie utrzymujemy ich, nie możemy upewnić się, że działają lub nie działają.
Ale nie możemy oczekiwać, że nasze programy się zablokują, gdy czekamy na odpowiedź tych usług. Mając to na uwadze, usługodawcy często projektują interfejsy API przy użyciu wzorca wywołania zwrotnego.
JavaScript bardzo ładnie obsługuje połączenia zwrotne, np. Z lambdami i zamknięciami. W świecie JavaScript istnieje duża aktywność, zarówno w przeglądarce, jak i na serwerze. Istnieją nawet platformy JavaScript opracowywane dla urządzeń mobilnych.
W miarę postępów coraz więcej z nas będzie pisać kod asynchroniczny, dla którego to zrozumienie będzie niezbędne.
Pamiętaj, że oddzwonienie to jedno słowo.
Strona zwrotna Wikipedii bardzo dobrze to wyjaśnia.
cytat ze strony wikipedii:
W programowaniu komputerowym wywołanie zwrotne to odwołanie do kodu wykonywalnego lub fragmentu kodu wykonywalnego, który jest przekazywany jako argument do innego kodu. Dzięki temu warstwa oprogramowania niższego poziomu może wywoływać podprogram (lub funkcję) zdefiniowany w warstwie wyższego poziomu.
Funkcja zwrotna to taka, którą należy wywołać, gdy spełniony zostanie określony warunek. Zamiast wywoływania natychmiastowego funkcja wywołania zwrotnego jest wywoływana w pewnym momencie w przyszłości.
Zwykle jest używany, gdy uruchamiane jest zadanie, które zakończy się asynchronicznie (tj. Zakończy się jakiś czas po powrocie funkcji wywołującej).
Na przykład funkcja żądania strony internetowej może wymagać od jej osoby wywołującej funkcji wywołania zwrotnego, która zostanie wywołana po zakończeniu pobierania strony internetowej.
"...when a condition is met"
ale myślałem, że wywołania zwrotne są wywoływane, gdy funkcja nadrzędna kończy wykonywanie i nie są zależne od warunków (?).
Połączenia zwrotne najłatwiej opisać w kategoriach systemu telefonicznego. Wywołanie funkcji jest analogiczne do dzwonienia do kogoś przez telefon, zadawania jej pytań, uzyskiwania odpowiedzi i rozłączania się; dodanie oddzwaniania zmienia analogię, więc po zadaniu jej pytania podajesz jej także swoje imię i numer, aby mogła oddzwonić z odpowiedzią.
- Paul Jakubik, „Implementacje wywołania zwrotnego w C ++”
Uważam, że ten żargon „oddzwaniania” został błędnie użyty w wielu miejscach. Moja definicja będzie taka:
Funkcja oddzwaniania to funkcja przekazywana komuś i umożliwiająca mu wywołanie go w pewnym momencie.
Myślę, że ludzie po prostu czytają pierwsze zdanie definicji wiki:
wywołanie zwrotne to odwołanie do kodu wykonywalnego lub fragmentu kodu wykonywalnego, który jest przekazywany jako argument do innego kodu.
Pracowałem z wieloma interfejsami API, zobacz różne złe przykłady. Wiele osób nazywa wskaźnik funkcji (odniesienie do kodu wykonywalnego) lub funkcje anonimowe (część kodu wykonywalnego) „callback”, jeśli są to tylko funkcje, dlaczego potrzebujesz do tego innej nazwy?
Właściwie tylko drugie zdanie w definicji wiki pokazuje różnice między funkcją zwrotną a funkcją normalną:
Dzięki temu warstwa oprogramowania niższego poziomu może wywoływać podprogram (lub funkcję) zdefiniowany w warstwie wyższego poziomu.
więc różnica polega na tym, kto przekaże funkcję i jak zostanie wywołana funkcja przekazana. Jeśli po prostu zdefiniujesz funkcję i przekażesz ją innej funkcji i wywołasz ją bezpośrednio w treści funkcji, nie nazywaj go wywołaniem zwrotnym. Definicja mówi, że przekazana funkcja zostanie wywołana przez funkcję „niższego poziomu”.
Mam nadzieję, że ludzie przestaną używać tego słowa w dwuznacznym kontekście, nie pomoże to lepiej zrozumieć, tylko gorzej.
Uprośćmy to. Co to jest funkcja oddzwaniania?
Przykład według przypowieści i analogii
Mam sekretarkę Każdego dnia proszę ją: (i) zostaw pocztę wychodzącą firmy na poczcie, a po tym, aby to zrobiła: (ii) cokolwiek zadanie, które napisałem dla niej na jednej z tych karteczek .
Jakie jest teraz zadanie na karteczce? Zadanie różni się z dnia na dzień.
Załóżmy, że w tym konkretnym dniu wymagam od niej wydrukowania niektórych dokumentów. Zapisuję to na karteczce i przypinam ją do jej biurka wraz z pocztą wychodzącą, którą musi wysłać.
W podsumowaniu:
Funkcja oddzwaniania to drugie zadanie: wydruk tych dokumentów. Ponieważ odbywa się to PO Zesłaniu poczty, a także dlatego, że wraz z pocztą, którą musi wysłać, zostaje jej przekazana karteczka samoprzylepna z informacją o wydrukowaniu dokumentu.
Połączmy to teraz ze słownictwem programistycznym
To wszystko. Nic więcej. Mam nadzieję, że to ci wyjaśniło - a jeśli nie, opublikuj komentarz, a ja postaram się wyjaśnić.
To sprawia, że wywołania zwrotne brzmią jak instrukcje zwrotne na końcu metod.
Nie jestem pewien, czy takie są.
Myślę, że wywołania zwrotne są w rzeczywistości wywołaniem funkcji, jako konsekwencja wywołania i zakończenia innej funkcji.
Myślę też, że oddzwanianie ma na celu adresowanie wywołania, w rodzaju „hej! Tego, o co prosiłeś? Zrobiłem to - pomyślałem, że dam ci znać - z powrotem do ciebie”.
Co to jest oddzwanianie ?
Co to jest funkcja oddzwaniania ?
otherFunction
) jako parametr, a funkcja zwrotna jest wywoływana (lub wykonywane) wewnątrz 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
W SOA funkcja zwrotna umożliwia modułom wtyczek dostęp do usług z kontenera / środowiska.
Analogia: oddzwanianie. Asynchroniczny. Nieblokujący
Przykład z życia dla oddzwaniania
Call After byłoby lepszą nazwą niż głupia nazwa, callback . Kiedy lub jeśli warunek zostanie spełniony w funkcji, wywołaj inną funkcję, funkcję Call After , tę otrzymaną jako argument.
Zamiast na stałe zakodować wewnętrzną funkcję w funkcji, pisze się funkcję, aby zaakceptować już zapisaną funkcję Call After jako argument. Funkcja Call After może zostać wywołana na podstawie zmian stanu wykrytych przez kod w funkcji odbierającej argument.
Funkcja wywołania zwrotnego to funkcja określona przez użytkownika do istniejącej funkcji / metody, która ma być wywoływana po zakończeniu akcji, wymaga dodatkowego przetwarzania itp.
Na przykład w JavaScript, a dokładniej jQuery, możesz określić argument wywołania zwrotnego, który ma być wywoływany po zakończeniu animacji.
W PHP preg_replace_callback()
funkcja ta umożliwia udostępnienie funkcji, która będzie wywoływana po dopasowaniu wyrażenia regularnego, z przekazaniem ciągów dopasowanych jako argumenty.
spójrz na obrazek :)
Główny program wywołuje funkcję biblioteki (która może być również funkcją na poziomie systemu) z nazwą funkcji zwrotnej. Ta funkcja zwrotna może być zaimplementowana na wiele sposobów. Główny program wybiera jedno wywołanie zwrotne zgodnie z wymaganiami.
Wreszcie funkcja biblioteki wywołuje funkcję wywołania zwrotnego podczas wykonywania.
Załóżmy, że mamy funkcję, w sort(int *arraytobesorted,void (*algorithmchosen)(void))
której może zaakceptować wskaźnik funkcji jako argument, którego można użyć w pewnym momencie sort()
implementacji. Następnie tutaj kod adresowany przez wskaźnik funkcji algorithmchosen
jest wywoływany jako funkcja zwrotna .
Zaletą jest to, że możemy wybrać dowolny algorytm, taki jak:
1. algorithmchosen = bubblesort
2. algorithmchosen = heapsort
3. algorithmchosen = mergesort ...
Które zostały, powiedzmy, zaimplementowane z prototypem:
1. `void bubblesort(void)`
2. `void heapsort(void)`
3. `void mergesort(void)` ...
Jest to koncepcja stosowana do osiągnięcia polimorfizmu w programowaniu obiektowym
„W programowaniu komputerowym wywołanie zwrotne to odniesienie do kodu wykonywalnego lub fragmentu kodu wykonywalnego, który jest przekazywany jako argument do innego kodu. Dzięki temu warstwa oprogramowania niższego poziomu może wywoływać podprogram (lub funkcję) zdefiniowany w warstwie wyższego poziomu. ” - Wikipedia
Oddzwanianie w C za pomocą wskaźnika funkcji
W C wywołanie zwrotne jest realizowane za pomocą wskaźnika funkcji. Wskaźnik funkcji - jak sama nazwa wskazuje, jest wskaźnikiem funkcji.
Na przykład int (* ptrFunc) ();
W tym przypadku ptrFunc jest wskaźnikiem do funkcji, która nie przyjmuje argumentów i zwraca liczbę całkowitą. NIE zapomnij umieścić w nawiasie, w przeciwnym razie kompilator przyjmie, że ptrFunc jest normalną nazwą funkcji, która nie bierze niczego i zwraca wskaźnik do liczby całkowitej.
Oto kod ilustrujący wskaźnik funkcji.
#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;
}
Teraz spróbujmy zrozumieć pojęcie wywołania zwrotnego w C za pomocą wskaźnika funkcji.
Cały program ma trzy pliki: callback.c, reg_callback.h i 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)();
}
Jeśli uruchomimy ten program, wynikiem będzie
Jest to program demonstrujący wywołanie zwrotne funkcji wewnątrz register_callback wewnątrz my_callback z powrotem w programie głównym
Funkcja wyższej warstwy wywołuje funkcję dolnej warstwy jako normalne wywołanie, a mechanizm zwrotny pozwala funkcji dolnej warstwy na wywołanie funkcji wyższej warstwy przez wskaźnik do funkcji wywołania zwrotnego.
Oddzwanianie w Javie za pomocą interfejsu
Java nie ma pojęcia wskaźnika funkcji. Implementuje mechanizm wywołania zwrotnego za pośrednictwem mechanizmu interfejsu. Zamiast wskaźnika funkcji deklarujemy interfejs posiadający metodę, która zostanie wywołana, gdy odbiorca zakończy swoje zadanie
Pokażę to na przykładzie:
Interfejs oddzwaniania
public interface Callback
{
public void notify(Result result);
}
Wzywający lub klasa wyższego poziomu
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
}
}
Funkcja Callee lub dolnej warstwy
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
}
}
Oddzwanianie za pomocą wzorca EventListener
Ten wzorzec służy do powiadamiania od 0 do n liczby obserwatorów / słuchaczy, że dane zadanie zostało zakończone
Różnica między mechanizmem wywoływania zwrotnego a mechanizmem EventListener / Observer polega na tym, że w wywołaniu zwrotnym odbiorca powiadamia pojedynczego rozmówcę, podczas gdy w Eventlisener / Observer odbiorca może powiadomić każdego, kto jest zainteresowany tym zdarzeniem (powiadomienie może przejść do niektórych innych części aplikacja, która nie uruchomiła zadania)
Pozwól, że wyjaśnię to na przykładzie.
Interfejs zdarzeń
public interface Events {
public void clickEvent();
public void longClickEvent();
}
Widżet klasy
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);
}
}
Przycisk klasy
public class Button extends Widget{
private String mButtonText;
public Button (){
}
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}
Pole wyboru klasy
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;
}
}
Klasa aktywności
pakiet 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();
}
}
Inna klasa
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...");
}
}
Główna klasa
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);
}
}
Jak widać z powyższego kodu, mamy interfejs zwany zdarzeniami, który zasadniczo zawiera listę wszystkich zdarzeń, które mogą wystąpić w naszej aplikacji. Klasa Widget jest klasą bazową dla wszystkich składników interfejsu użytkownika, takich jak Button, Checkbox. Te składniki interfejsu użytkownika są obiektami, które faktycznie odbierają zdarzenia z kodu frameworka. Klasa widżetów implementuje interfejs zdarzeń, a także ma dwa zagnieżdżone interfejsy, a mianowicie OnClickEventListener i OnLongClickEventListener
Te dwa interfejsy są odpowiedzialne za nasłuchiwanie zdarzeń, które mogą wystąpić w komponentach interfejsu użytkownika pochodzących z widgetów, takich jak Button lub Checkbox. Jeśli więc porównamy ten przykład z wcześniejszym przykładem wywołania zwrotnego przy użyciu interfejsu Java, te dwa interfejsy działają jako interfejs wywołania zwrotnego. Zatem kod wyższego poziomu (działanie tutaj) implementuje te dwa interfejsy. I ilekroć wystąpi zdarzenie w widgecie, wywoływany będzie kod wyższego poziomu (lub metoda tych interfejsów zaimplementowana w kodzie wyższego poziomu, czyli tutaj Działanie).
Teraz pozwól mi omówić podstawową różnicę między wzorcem wywołania zwrotnego a listą zdarzeń. Jak już wspomnieliśmy, za pomocą funkcji oddzwaniania Callee może powiadomić tylko jednego rozmówcę. Ale w przypadku wzorca EventListener każda inna część lub klasa aplikacji może zarejestrować zdarzenia, które mogą wystąpić w przycisku lub polu wyboru. Przykładem tego rodzaju klasy jest OtherClass. Jeśli zobaczysz kod OtherClass, przekonasz się, że zarejestrował się on jako detektor ClickEvent, który może wystąpić w przycisku zdefiniowanym w działaniu. Ciekawe jest to, że oprócz działania (dzwoniącego), ten OtherClass będzie również powiadamiany za każdym razem, gdy nastąpi kliknięcie przycisku.
Funkcja zwrotna to funkcja przekazywana (jako odwołanie lub wskaźnik) do określonej funkcji lub obiektu. Ta funkcja lub obiekt wywoła tę funkcję w dowolnym momencie później, być może wiele razy, w dowolnym celu:
...
Zatem opis wywołania zwrotnego jako funkcji wywoływanej na końcu innej funkcji lub zadania jest nadmiernie uproszczony (nawet jeśli jest to częsty przypadek użycia).
Wywołanie zwrotne jest pomysłem przekazania funkcji jako parametru do innej funkcji i wywołania jej po zakończeniu procesu.
Jeśli otrzymujesz koncepcję oddzwonienia poprzez niesamowite odpowiedzi powyżej, polecam powinieneś zapoznać się z tłem jej pomysłu.
„Co skłoniło ich (informatyków) do wywołania zwrotnego?” Możesz nauczyć się problemu, który polega na blokowaniu (szczególnie blokowaniu interfejsu użytkownika), a wywołanie zwrotne nie jest jedynym rozwiązaniem. Istnieje wiele innych rozwiązań (np .: Wątek, Futures, Obietnice ...).
Jednym z ważnych obszarów użytkowania jest zarejestrowanie jednej ze swoich funkcji jako uchwytu (tj. Oddzwanianie), a następnie wysłanie wiadomości / wywołanie jakiejś funkcji w celu wykonania pracy lub przetwarzania. Teraz po zakończeniu przetwarzania wywoływana funkcja wywoła naszą zarejestrowaną funkcję (tzn. Teraz oddzwonienie jest zakończone), co oznacza, że przetwarzanie zostało zakończone.
Ten link do Wikipedii dość dobrze wyjaśnia graficznie.
Funkcja zwrotna, znana również jako funkcja wyższego rzędu, jest funkcją przekazywaną do innej funkcji jako parametr, a funkcja zwrotna jest wywoływana (lub wykonywana) wewnątrz funkcji nadrzędnej.
$("#button_1").click(function() {
alert("button 1 Clicked");
});
Tutaj przekazaliśmy funkcję jako parametr do metody click. I metoda click wywoła (lub wykona) przekazaną do niej funkcję zwrotną.
Funkcja zwrotna Funkcja przekazana do innej funkcji jako argument.
function test_function(){
alert("Hello world");
}
setTimeout(test_function, 2000);
Uwaga: W powyższym przykładzie funkcja test_funkcja została użyta jako argument funkcji setTimeout.