Czytam książkę programming in Lua
. Powiedział tak
Zamknięcia stanowią cenne narzędzie w wielu kontekstach. Jak widzieliśmy, są one przydatne jako argumenty dla funkcji wyższego rzędu, takich jak sortowanie. Zamknięcia są cenne dla funkcji, które również budują inne funkcje, jak na przykład nasz nowy licznik; ten mechanizm pozwala programom Lua na stosowanie zaawansowanych technik programowania ze świata funkcjonalnego. Zamknięcia są również przydatne w przypadku funkcji oddzwaniania. Typowy przykład występuje tutaj, gdy tworzysz przyciski w konwencjonalnym zestawie narzędzi GUI. Każdy przycisk ma funkcję wywołania zwrotnego, którą należy wywołać, gdy użytkownik naciśnie przycisk; chcesz, aby różne przyciski wykonywały nieco inne czynności po naciśnięciu. Na przykład kalkulator cyfrowy potrzebuje dziesięciu podobnych przycisków, po jednym dla każdej cyfry. Możesz utworzyć każdy z nich za pomocą funkcji takiej jak ta:
function digitButton (digit)
return Button{label = tostring(digit),
action = function ()
add_to_display(digit)
end}
end
Wygląda na to, że jeśli zadzwonię digitButton
, zwróci action
(spowoduje to zamknięcie), więc mogę uzyskać dostęp do digit
przekazanego digitButton
.
Moje pytanie brzmi:
Why we need call back functions? what situations can I apply this to?
Autor powiedział:
W tym przykładzie zakładamy, że Button to funkcja zestawu narzędzi, która tworzy nowe przyciski; etykieta to etykieta przycisku; a działanie to zamknięcie oddzwaniania, które ma zostać wywołane po naciśnięciu przycisku. Oddzwonienie można wywołać długo po tym, jak digitButton wykonał swoje zadanie i po tym, jak cyfra zmiennej lokalnej wyszła poza zakres, ale nadal może uzyskać dostęp do tej zmiennej.
według autora, myślę, że podobny przykład jest taki:
function Button(t)
-- maybe you should set the button here
return t.action -- so that you can call this later
end
function add_to_display(digit)
print ("Display the button label: " .. tostring(digit))
end
function digitButton(digit)
return Button{label = tostring(digit),
action = function ()
add_to_display(digit)
end}
end
click_action = digitButton(10)
click_action()
a zatem, the callback can be called a long time after digitButton did its task and after the local variable digit went out of scope.
Odpowiedzi:
Facet 1 do Facet 2: hej koleś Chcę coś zrobić, gdy użytkownik kliknie tam, oddzwoń, kiedy to się stanie, dobrze?
Guy 2 oddzwania do Guy 1, gdy użytkownik kliknie tutaj.
źródło
Nie, to nigdy nie zwróci akcji. Przycisk wykona go, gdy użytkownik go kliknie. I to jest odpowiedź. Potrzebujesz funkcji zwrotnych, jeśli chcesz zdefiniować działania, które powinny się zdarzyć w innym komponencie w reakcji na zdarzenie, którego nie kontrolujesz (pętla zdarzeń, która jest częścią systemu, wykona metodę przycisku, która z kolei wykona akcja).
źródło
Myślę, że lepszym przykładem użycia wywołań zwrotnych są funkcje asynchroniczne. Nie mogę mówić za Luą, ale w JavaScript jedną z najczęstszych akcji asynchronicznych jest kontaktowanie się z serwerem za pośrednictwem AJAX.
Wywołanie AJAX jest asynchroniczne, co oznacza, że jeśli zrobisz coś takiego:
zawartość
if
bloku nie będzie działać niezawodnie, a gdy tak się dzieje, dzieje się tak tylko dlatego, żeajaxCall()
funkcja zakończyła się, zanim wykonanie dotarło doif
instrukcji.Jednak wywołania zwrotne eliminują ten problem, zapewniając zakończenie połączenia asynchronicznego przed wywołaniem wymaganej funkcji. Twój kod zmieni się na coś takiego:
Ma to na celu umożliwienie ci wykonywania takich czynności, jak zbieranie danych, bez ingerencji w inne rzeczy, takie jak rysowanie interfejsu. Jeśli gromadzenie danych było synchroniczne, interfejs przestałby reagować, gdy aplikacja czekała na pobranie danych. Brak odpowiedzi interfejsu jest bardzo niekorzystny dla wygody użytkownika, ponieważ większość użytkowników uzna, że aplikacja „uległa awarii” i spróbuje przerwać proces.
Aby zobaczyć to w działaniu, wystarczy spojrzeć na każdą stronę internetową, która dokonuje dowolnego rodzaju aktualizacji bez ponownego ładowania całej strony. Dobrym przykładem są serwisy Twitter, LinkedIn i StackExchange. „Niekończące się przewijanie” kanałów Twittera i powiadomienia SE (zarówno dla powiadomień użytkowników, jak i powiadomień, że pytanie ma nową aktywność), są obsługiwane przez połączenia asynchroniczne. Kiedy widzisz gdzieś pokrętło, oznacza to, że sekcja wykonała asynchroniczne wywołanie i czeka na zakończenie tego połączenia, ale możesz wchodzić w interakcje z innymi rzeczami w interfejsie (a nawet wykonywać inne wywołania asynchroniczne). Po zakończeniu tego połączenia zareaguje i odpowiednio zaktualizuje interfejs.
źródło
Zadałeś pytanie
Postaram się odpowiedzieć na to w zwięzły i jasny sposób (jeśli mi się nie uda, zapoznaj się z linkiem wiki na dole tej odpowiedzi).
Oddzwanianie służy do odroczenia konkretnej implementacji czegoś do ostatniej możliwej chwili.
Przykład przycisku jest dobrą ilustracją tego. Załóżmy, że chcesz mieć przycisk w aplikacji, który drukuje stronę na drukarce, możemy sobie wyobrazić świat, w którym w tym celu musiałbyś napisać całą nową
PrinterButton
klasę.Na szczęście mamy pojęcie wywołania zwrotnego (dziedziczenie i użycie wzorca szablonu jest również rodzajem semantycznego wywołania zwrotnego), więc nie musimy tego robić.
Zamiast ponownie wdrażać każdy aspekt przycisku, robimy to, aby dodać do implementacji przycisku.
Button
Ma pojęcie robi coś , gdy jest wciśnięty. Po prostu mówimy, co to jest.Ten mechanizm wstrzykiwania zachowań do frameworków nazywa się callbackami.
Przykład:
Wprowadźmy zachowanie do przycisku HTML:
W tym przypadku
onclick
wskazuje na wywołanie zwrotne, którym w tym przykładzie jestprint()
metoda.http://en.wikipedia.org/wiki/Callback_(computer_programming)
źródło
Funkcje oddzwaniania są bardzo przydatne w programowaniu sterowanym zdarzeniami. Pozwalają na skonfigurowanie programu w taki sposób, aby zdarzenia wyzwalały prawidłowy kod. Jest to bardzo powszechne w programach z GUI, w których użytkownicy mogą kliknąć dowolny element interfejsu użytkownika (np. Przyciski lub pozycje menu), a odpowiedni kod zostanie uruchomiony.
źródło
Co dzieje się bez połączeń zwrotnych:
Facet 1: Dobra, czekam na to, co się stanie. (gwizdki, kciuki kręci)
Facet 2: Cholera! Dlaczego facet 1 nie pokazuje mi rzeczy? Chcę zobaczyć, jak dzieją się rzeczy !! Gdzie są moje rzeczy? Jak ktokolwiek ma tu coś zrobić?
źródło
Po pierwsze, termin callback odnosi się do zamknięcia, które jest używane do czegoś.
Załóżmy na przykład, że tworzysz funkcję zamknięcia i po prostu przechowujesz ją w zmiennej. To nie jest oddzwanianie, ponieważ nie jest używane do niczego.
Załóżmy jednak, że tworzysz zamknięcie i przechowujesz je w miejscu, w którym zostanie wywołane, gdy coś się wydarzy. To jest teraz nazywane oddzwonieniem.
Zwykle wywołania zwrotne są tworzone przez inne części programu niż części, które je wywołują. Łatwo więc sobie wyobrazić, że niektóre części programu „oddzwaniają” do innych części.
Mówiąc najprościej, wywołania zwrotne pozwalają jednej części programu powiedzieć innej części, aby coś zrobiła (cokolwiek), gdy coś się wydarzy.
Jeśli chodzi o zmienne utrzymywane przy życiu z powodu użycia ich w zamknięciu, jest to zupełnie inna funkcja zwana upvalues (aka „przedłużająca żywotność zmiennych lokalnych” wśród tych, którzy nie mówią Lua). I to jest całkiem przydatne.
źródło
Extending the lifetime of local variables
to także określenieupvalue
.Oddzwanianie pojawiło się przynajmniej od pierwszych dni Fortran. Na przykład, jeśli masz solver ODE (zwykłe równanie różniczkowe), taki jak solver Runge-Kutta, może to wyglądać następująco:
Umożliwia dzwoniącemu dostosowanie zachowania podprogramu poprzez przekazanie mu funkcji specjalnego przeznaczenia, która może być wywoływana w razie potrzeby. Pozwala to na użycie solvera ODE do symulacji szerokiej gamy systemów.
źródło
Natknąłem się na to i chciałem dostarczyć bardziej aktualną odpowiedź ...
Funkcje zwrotne pozwalają nam zrobić coś z danymi w późniejszym czasie, pozwalając na uruchomienie reszty naszego kodu, zamiast czekać na to. Kod asynchroniczny pozwala nam na luksus wykonywania wszystkiego później . Najbardziej czytelnym przykładem funkcji oddzwaniania, na które natrafiłem, są obietnice w JavaScript. W poniższym przykładzie każdym razem, gdy widzisz funkcję (wynik) lub (newResult) lub (finalResult) ... są to funkcje zwrotne. Kod w nawiasach klamrowych jest wykonywany po powrocie danych z serwera. Tylko w tym momencie sensowne byłoby wykonywanie tych funkcji, ponieważ teraz potrzebne im dane są dostępne.
kod pochodzi z ... https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
Mam nadzieję, że to komuś pomaga. To pomogło mi zrozumieć oddzwonienia :)
źródło
Nie znam lua, ale w ogólnych metodach wywoływania zwrotnego niektóre przypominają wielowątkowość. Na przykład w programowaniu aplikacji mobilnych większość aplikacji działa jak wysyłanie żądań do serwera i zabawa z interfejsem użytkownika z danymi pochodzącymi z odpowiedzi serwera. Gdy użytkownik wysyła żądanie do serwera, uzyskanie odpowiedzi z serwera zajmie trochę czasu, ale dla najlepszego interfejsu użytkownika UX nie powinien się blokować.
Z tego powodu używamy wielu wątków do wykonywania operacji równoległych. Gdy otrzymamy odpowiedź z serwera, musimy zaktualizować interfejs użytkownika. z tego wątku musimy powiadomić o aktualizacji. ze świata funkcjonalnego. Ten typ wywołań funkcji nazywa się metodami wywołania zwrotnego. Kiedy wywołasz te metody, kontroler powinien powrócić do głównego wątku. Na przykład metodami wywołania zwrotnego są bloki w celu C.
źródło