Rozumiem pomysł wywołania zwrotnego, w którym przekazuję funkcję do innej funkcji, a następnie ta funkcja korzysta z dostarczonej funkcji do woli.
Z trudem rozumiem odroczenie oddzwaniania, nawet po googlowaniu.
Czy ktoś mógłby podać proste wyjaśnienie? Programuję w Ruby, ale znam również C / C ++, ale przede wszystkim byłem doświadczonym programistą w asemblerze. Zastanawiam się więc, czy to trochę jak stos adresów zwrotnych, które się pojawiają? Mam nadzieję nauczyć się jquery lub node.js i te odroczone wywołania zwrotne wydają się integralną częścią obu. Rozumiem podstawowe zasady wątków (choć obiekt mutex powoduje ból głowy;)
Deferred
obiekty jQuery ? Czy chodzi o coś specyficznego dla Node.js?Odpowiedzi:
Na życzenie oto komentarze przedstawione jako odpowiedź:
Nie jestem pewien, czy całkowicie rozumiesz fakt, że funkcje w JS są obiektami pierwszej klasy i dlatego mogą być przechowywane do czasu, gdy będą potrzebne, po czasie ich utworzenia.
Na przykład powiedz, że chcesz zapisać do pliku, a następnie wydrukuj komunikat w dzienniku; więc wywołujesz funkcję „write ()” (lub cokolwiek innego) i przekazujesz jej funkcję, która generuje komunikat dziennika (jest to funkcja odroczonego oddzwaniania). „write ()” wewnętrznie przechowuje odniesienie do podanej funkcji, rozpoczyna zapis do pliku i ustawia własne wywołanie zwrotne, aby wiedzieć, kiedy zapis zostanie zakończony. Następnie powraca przed zakończeniem zapisu; kiedy to jest, wewnętrzne wywołanie zwrotne jest w jakiś sposób wywoływane (jest to zadanie frameworku - w przypadku node.js odbywa się to za pomocą pętli zdarzeń), która następnie wywołuje wywołanie zwrotne, które drukuje komunikat dziennika.
Część „odroczona” oznacza po prostu, że twoja funkcja zwrotna nie jest wywoływana od razu; wywoływanie go jest odraczane do odpowiedniego czasu. W przypadku funkcji asynchronicznych, takich jak wiele w node.js, dane wywołanie zwrotne jest generalnie wywoływane po zakończeniu operacji (lub wystąpi błąd).
Większość rzeczy jest asynchroniczna w node.js, ale w przeglądarce np. JQuery, większość rzeczy jest faktycznie synchroniczna (z wyjątkiem, oczywiście, dla żądań AJAX). Ponieważ funkcje pierwszej klasy są tak przydatne w JavaScript (szczególnie ze względu na doskonałą obsługę zamykania), wywołania zwrotne są również używane wszędzie w przeglądarce, ale nie są „odraczane” dla operacji synchronicznych (z wyjątkiem przypadków, gdy nie są wywoływane natychmiast przez Ty, ale później przez funkcję, którą wywołujesz).
Fakt, że system bazowy jest sterowany zdarzeniami, jest ortogonalny wobec korzystania z odroczonych wywołań zwrotnych; możesz sobie wyobrazić (bardzo wolną) wersję node.js, która uruchamiała wątek dla każdej operacji, a następnie wywołała określone wywołanie zwrotne, gdy wątek zakończył pracę, w ogóle nie wykorzystując zdarzeń. Oczywiście jest to okropny model, ale ilustruje mój punkt widzenia :-)
źródło
Działanie odroczonego wywołania zwrotnego polega na każdym dodaniu do niego wywołania zwrotnego, które jest wypychane do tablicy. Następnie, gdy wywoływana jest metoda
.resolve()
lub.resolveWith()
na odroczonym obiekcie, wszystkie.done()
wywołania zwrotne w tablicy są wykonywane w kolejności.Teraz możemy spojrzeć na to, czym jest Odroczony Obiekt. Weź poniższy fragment jako przykład.
To, co mamy teraz, to odroczony obiekt i obietnica odroczonego obiektu. Odroczony obiekt ma wszystkie te same metody jak obiektu Obiecuję jednak przedmiotem obietnica ma tylko metody
.done()
,.fail()
i.always()
które są stosowane, aby dodać callbacków odroczonego obiektu dla siebie odpowiednievent
. Z drugiej strony odroczony obiekt ma kilka innych metod, przede wszystkim.resolve()
i.reject()
. Po wywołaniu tych metod w odroczonym obiekcie wywoływane są wszystkie wywołania zwrotne..resolve()
odpala.done()
i.always()
wywołania zwrotne, podczas gdy wywołania.reject()
metody.fail()
i.always()
wywołania zwrotne.Zasadniczo odroczony obiekt jest ukryty w zakresie prywatnym, a obiekt obietnicy jest zwracany z funkcji, aby można było na nim umieścić wywołania zwrotne. Odroczony obiekt zostanie rozwiązany później, na przykład po zakończeniu żądania ajax lub po załadowaniu obrazu, po ustawieniu limitu czasu itp. Ważne jest również, aby zdawać sobie sprawę, że odroczony obiekt można rozwiązać tylko raz. Jeśli problem został już rozwiązany, wywołania zwrotne zostaną natychmiast wywołane.
Oto inny przykład, którego używam:
Aby uzyskać więcej informacji na temat
$.Deferred()
metody jQuery i obiektów odroczonych, odwiedź http://api.jquery.com/category/deferred-object/źródło
Nie jestem pewien, ale uważam, że odroczone oddzwonienie odnosi się do asynchronicznego oddzwonienia, więc lepiej będzie, jeśli będziesz go szukać w Google.
Najlepsze wytłumaczenie, jakie znalazłem, to http://www.nodebeginner.org
W tym przykładzie prawdopodobnieExpensiveFunction jest funkcją nieblokującą (lub funkcją asynchroniczną). Oznacza to, że nie jest on wykonywany od razu, ale umieszczany w tak zwanej pętli zdarzeń. Wątek node.js będzie kontynuował wykonywanie, ale w pewnym momencie zdecyduje się wykonać coś z pętli zdarzeń. Kiedy osiągnie prawdopodobnieExpensiveFunction, wywołuje ją, a kiedy prawdopodobnieExpensiveFunction kończy wykonywanie, wywołuje (odroczone) wywołanie zwrotne przekazane jako parametr do niego.
Jako przykład prawdopodobnieExpensiveFunction możesz wziąć fs.readFile
źródło
.resolve()
lub.reject()
na oryginalnym odroczonym obiekcie wywoływana jest lista oddzwonień.JavaScript jest jednowątkowy, więc nie możesz myśleć w kategoriach wątków, aby to zrozumieć. Oto przykład zwykłych i asynchronicznych wywołań zwrotnych przy użyciu jQuery:
źródło
Odroczone wywołania zwrotne (inaczej Promices ) umożliwiają pisanie sekwencyjnego kodu asynchronicznego, bez bólu i spaghetti zwrotnego:
„when” pozwala poczekać, aż funkcje powrócą równolegle, i
then
może być sekwencyjnie powiązane.jedna uwaga: jQuery odroczony ! = Obietnice / A , ich składnia jest nieco inna.
Istnieją dobre artykuły na ten temat: jeden na IEBlog, a drugi na jakimś losowym blogu , książka i popularne pytanie dotyczące nakładania stosów
źródło