W tym samouczku dowiemy się o generatorach i ich różnicach z wywołaniami zwrotnymi
Co to są generatory?
Generatory stały się ostatnio dość popularne w Node.js, a to prawdopodobnie dzięki temu, co potrafią.
- Generatory to funkcje, które można zawiesić i wznowić w późniejszym czasie.
- Generatory są przydatne podczas wykonywania takich pojęć, jak „leniwe wykonywanie”. Zasadniczo oznacza to, że wstrzymując wykonywanie i wznawiając je do woli, jesteśmy w stanie pobierać wartości tylko wtedy, gdy jest to konieczne.
Generatory mają poniższe 2 kluczowe metody
- Metoda yield - metoda yield jest wywoływana w funkcji w celu zatrzymania wykonywania funkcji w określonym wierszu, w którym wywoływana jest metoda yield.
- Next method - ta metoda jest wywoływana z aplikacji głównej w celu wznowienia wykonywania funkcji, która ma metodę yield. Wykonywanie funkcji będzie kontynuowane do następnej metody yield lub do końca metody.
Spójrzmy na przykład, jak można wykorzystać generatory.
W naszym przykładzie będziemy mieć prostą funkcję Add, która doda 2 liczby, ale będziemy nadal zatrzymywać wykonywanie metody w różnych punktach, aby pokazać, jak można używać generatorów.
function* Add(x) {yield x + 1;var y = yield(null);y = 6return x + y;}var gen = Add(5);gen.next();gen.next();
Objaśnienie kodu: -
- Pierwszym krokiem jest zdefiniowanie funkcji naszego generatora. Zauważ, że jest to robione przez dodanie „*” do słowa kluczowego function. Następnie definiujemy funkcję o nazwie Add, która przyjmuje parametr x.
- Słowo kluczowe yield jest specyficzne dla generatorów. To sprawia, że jest to potężna konstrukcja do wstrzymywania funkcji w środku czegokolwiek. Zatem tutaj wykonywanie funkcji zostanie zatrzymane do czasu wywołania funkcji next (), co zostanie wykonane w kroku 4. W tym momencie wartość x wyniesie 6, a wykonywanie funkcji zostanie zatrzymane.
- W tym miejscu najpierw wywołujemy funkcję generatora i wysyłamy wartość 5 do naszej funkcji Add. Ta wartość zostanie podstawiona w parametrze x naszej funkcji Add.
- Po wywołaniu funkcji next () funkcja Add () wznowi wykonywanie. Kiedy następna instrukcja var y = yield (null) zostanie wykonana, funkcja Add () ponownie przestanie działać.
- Teraz po ponownym wywołaniu funkcji next () zostaną uruchomione następne instrukcje, a połączona wartość x = 5 i y = 6 zostanie dodana i zwrócona.
Wywołania zwrotne a generatory
Generatory służą do rozwiązania problemu tzw. Piekła zwrotnego. Czasami funkcje zwrotne stają się tak zagnieżdżone podczas tworzenia aplikacji Node.js, że korzystanie z funkcji zwrotnych staje się po prostu zbyt skomplikowane.
Tutaj przydają się generatory. Jednym z najczęstszych przykładów jest tworzenie funkcji timera.
Zobaczmy poniższy przykład, w jaki sposób generatory mogą okazać się przydatne w przypadku wywołań zwrotnych.
Nasz przykład stworzy prostą funkcję opóźnienia czasowego. Następnie chcielibyśmy wywołać tę funkcję z opóźnieniem 1000, 2000 i 3000 ms.
Krok 1) Zdefiniuj naszą funkcję oddzwaniania z niezbędnym kodem opóźnienia czasowego.
function Timedelay(ptime, callback) {setTimeout(function() {callback("Pausing for " + ptime);}, time);}
Objaśnienie kodu: -
- Tutaj tworzymy funkcję o nazwie Timedelay z parametrem o nazwie ptime. Zajmie to niezbędne opóźnienie czasowe, które chcemy wprowadzić w naszej aplikacji.
- Następnym krokiem jest po prostu utworzenie wiadomości, która zostanie wyświetlona użytkownikowi z informacją, że aplikacja będzie wstrzymana przez te wiele milisekund.
Krok 2) Spójrzmy teraz na kod, gdybyśmy włączali wywołania zwrotne. Załóżmy, że chcieliśmy uwzględnić wywołania zwrotne w oparciu o wartości 1000, 2000 i 3000 milisekund, poniższy kod pokazuje, jak musielibyśmy je zaimplementować za pomocą wywołań zwrotnych.
Timedelay(1000, function(message) {console.log(msg);Timedelay(2000, function(message) {console.log(msg);Timedelay(3000, function(message) {console.log(msg);})})})
Objaśnienie kodu: -
- Wzywamy Timedelay jako callback z wartością 1000.
- Następnie chcemy ponownie wywołać funkcję Timedelay z wartością 2000.
- Na koniec chcemy ponownie wywołać funkcję Timedelay z wartością 3000.
Z powyższego kodu widać, że staje się bardziej nieuporządkowany, ponieważ chcemy wielokrotnie wywoływać funkcję.
Krok 3) Teraz zobaczmy, jak zaimplementować ten sam kod za pomocą generatorów. Z poniższego kodu możesz teraz zobaczyć, jak proste stało się zaimplementowanie funkcji Timedelay przy użyciu generatorów.
function* Messages() {console,log(yield(Timedelay(1000, function(){})));console,log(yield(Timedelay(2000, function(){})));console,log(yield(Timedelay(3000, function(){})));}
Objaśnienie kodu: -
- Najpierw definiujemy funkcję generatora, która będzie używana do wywołania naszej funkcji Timedelay.
- Wzywamy funkcję Yield wraz z funkcją Timedelay z wartością 1000 jako wartością parametru.
- Następnie wywołujemy funkcję Yield wraz z funkcją Timedelay z 2000 jako wartością parametru.
- Na koniec wywołujemy funkcję Yield wraz z funkcją Timedelay z wartością 3000 jako wartością parametru.
Podsumowanie
Generatory mogą być również używane do łagodzenia problemów z zagnieżdżonymi wywołaniami zwrotnymi i pomagają w usuwaniu tego, co jest znane jako piekło wywołań zwrotnych. Generatory służą do zatrzymywania przetwarzania funkcji. Odbywa się to za pomocą metody „yield” w funkcji asynchronicznej.