Słyszałem o słowie kluczowym „wydajność” w JavaScript, ale znalazłem bardzo słabą dokumentację na jego temat. Czy ktoś może mi wyjaśnić (lub polecić witrynę, która wyjaśnia) jego użycie i do czego służy?
javascript
yield
keyword
mck89
źródło
źródło
Odpowiedzi:
Dokumentacja MDN jest całkiem dobra, IMO.
źródło
Późne odpowiedzi, prawdopodobnie wszyscy wiedzą o tym
yield
teraz, ale pojawiła się lepsza dokumentacja.Na podstawie przykładu Jamesa Longa z „Javascript's Future: Generators” dla oficjalnego standardu Harmony:
To
yield
coś w rodzajureturn
: dostajesz coś z powrotem.return x
zwraca wartośćx
, aleyield x
zwraca funkcję, która daje metodę iteracji w kierunku następnej wartości. Przydatne, jeśli masz procedurę potencjalnie obciążającą pamięć, którą możesz chcieć przerwać podczas iteracji.źródło
function* foo(x){
tam jest*
token . To, czy jest to potrzebne, zależy od tego, jaką przyszłość powrócisz. Szczegół jest długi: GvR wyjaśnia to dla implementacji Pythona , na której modelowana jest implementacja JavaScript. Używaniefunction *
zawsze będzie właściwe, choć w niektórych przypadkach jest nieco większe niż wfunction
przypadkuyield
.function *
iyield
, i dodała cytowany błąd („Wczesny błąd powstaje, jeśli wydajność lub wyrażenie * występuje w funkcji innej niż generator”). Ale oryginalna implementacja Javascript 1.7 w Firefoksie nie wymagała*
. Zaktualizowałem odpowiednio odpowiedź. Dzięki!To jest naprawdę proste, tak to działa
yield
Słowo kluczowe pomaga po prostu wstrzymać i wznowić funkcję w dowolnym momencie asynchronicznie .Weź tę prostą funkcję generatora :
Do czasu wywołania _process.next () to przyzwyczajenie wykonywania przez pierwsze 2 linie kodu, to pierwszy plon będzie wstrzymać funkcję. Aby wznowić funkcję do następnego punktu pauzy ( słowo kluczowe wydajności ), musisz wywołać _process.next () .
Ale jednocześnie wykonuje yield to wstrzymać i wznowić zachowań może powrócić pewne rezultaty , jak również
{value: any, done: boolean}
zgodnie z poprzedniej funkcji my nie emitują żadnych wartości. Jeśli zbadamy poprzednie wyjście, pokaże to samo{ value: undefined, done: false }
z niezdefiniowaną wartością .Pozwala zagłębić się w słowo kluczowe wydajności. Opcjonalnie możesz dodać wyrażenie i ustawić przypisanie domyślnej wartości opcjonalnej . (Oficjalna składnia dokumentu)
wyrażenie : wartość do zwrócenia z funkcji generatora
rv : Zwraca opcjonalną wartość, która została przekazana do metody next () generatora
Spróbuj teraz
Zastosowania
Bibliografia:
źródło
Upraszczając / opracowując odpowiedź Nicka Sotirosa (co moim zdaniem jest niesamowite), myślę, że najlepiej opisać, jak zacząć kodować
yield
.Moim zdaniem największą zaletą używania
yield
jest to, że wyeliminuje wszystkie zagnieżdżone problemy zwrotne, które widzimy w kodzie. Trudno na początku zrozumieć, dlatego postanowiłem napisać tę odpowiedź (dla siebie i mam nadzieję, że inni!)Robi to, wprowadzając ideę rutyny, która jest funkcją, która może dobrowolnie zatrzymać / wstrzymać, dopóki nie osiągnie tego, czego potrzebuje. W javascript jest to oznaczone przez
function*
.function*
Można używać tylko funkcjiyield
.Oto typowy javascript:
Jest to niezgrabne, ponieważ teraz cały kod (który oczywiście musi czekać na to
loadFromDB
wywołanie) musi znajdować się w tym brzydko wyglądającym wywołaniu zwrotnym. Jest to złe z kilku powodów ...})
którego musisz wszędzie śledzićfunction (err, result)
żargonresult
Z drugiej strony,
yield
wszystko to można zrobić w jednym wierszu za pomocą ładnego wspólnego schematu.I tak teraz twoja główna funkcja przyniesie w razie potrzeby, gdy będzie musiała czekać na załadowanie zmiennych i rzeczy. Ale teraz, aby to uruchomić, musisz wywołać normalną (nieskorupcyjną funkcję). Prosta wspólna struktura może rozwiązać ten problem, więc wystarczy, że uruchomisz:
I początek jest zdefiniowany (z odpowiedzi Nicka Sotiro)
A teraz możesz mieć piękny kod, który jest o wiele bardziej czytelny, łatwy do usunięcia i nie musisz majstrować przy wcięciach, funkcjach itp.
Ciekawym spostrzeżeniem jest to, że w tym przykładzie
yield
jest to po prostu słowo kluczowe, które można umieścić przed funkcją z wywołaniem zwrotnym.Wydrukowałby „Hello World”. Więc możesz faktycznie zmienić dowolną funkcję zwrotną w użycie
yield
, po prostu tworząc tę samą sygnaturę funkcji (bez cb) i zwracającfunction (cb) {}
, tak jak poniżej:Mam nadzieję, że dzięki tej wiedzy możesz napisać czystszy, bardziej czytelny kod, który można łatwo usunąć !
źródło
function*
jest zwykłą funkcją bez wydajności?function *
jest to funkcja, która zawiera wydajność. Jest to specjalna funkcja zwana generatorem.yield
wszędzie, jestem pewien, że ma to większy sens niż wywołania zwrotne, ale nie rozumiem, w jaki sposób jest to bardziej czytelne niż wywołania zwrotne.Aby dać pełną odpowiedź:
yield
działa podobniereturn
, ale w generatorze.W przypadku często podawanego przykładu działa to w następujący sposób:
Ale jest też drugi cel słowa kluczowego wydajności. Można go użyć do przesłania wartości do generatora.
Aby wyjaśnić, mały przykład:
Działa to, jak
2
przypisuje się wartośćy
, wysyłając ją do generatora po zatrzymaniu z pierwszą wydajnością (która zwróciła0
).To pozwala nam na naprawdę fajne rzeczy. (spójrz na coroutine)
źródło
Służy do generowania iteratorów. Zasadniczo pozwala na utworzenie (potencjalnie nieskończonej) sekwencji przy użyciu kodu proceduralnego. Zobacz dokumentację Mozilli .
źródło
yield
może być również użyty do wyeliminowania piekła wywołania zwrotnego, dzięki ramowej strukturze.źródło
Generator sekwencji Fibonacciego wykorzystujący słowo kluczowe fed.
źródło
Yeild
słowo kluczowe w funkcji javaScript powoduje, że jest generatorem,co to jest generator w javaScript?
Generatory znaczeń pomagają nam pracować asynchronicznie z iteratorami pomocy. Och, czym są iteratory hacka? naprawdę?
skąd iterator pomaga nam uzyskiwać dostęp do elementu pojedynczo? pomaga nam uzyskać dostęp do przedmiotów poprzez funkcje generatora,
funkcje generatora to te, w których używamy
yeild
słowa kluczowego, słowo kluczowe wydajności pomaga nam w wstrzymywaniu i wznawianiu wykonywania funkcjiOto szybki przykład
pozwól mi wyjaśnić, co się dzieje
zauważyłeś, że wykonanie jest wstrzymywane przy każdym
yeild
słowie kluczowym, a my możemy uzyskać do niego dostępyield
za pomocą iteratora.next()
powoduje to powtarzanie wszystkich
yield
słów kluczowych pojedynczo, a następnie zwraca niezdefiniowane, gdy nie ma jużyield
słów kluczowych w prostych słowach, które można wypowiedziećyield
słowo kluczowe jest punktem przerwania, w którym funkcja za każdym razem zatrzymuje się i wznawia tylko po wywołaniu za pomocą iteratoraw naszym przypadku:
_getMeDrink.next()
jest to przykład iteratora, który pomaga nam uzyskać dostęp do każdego punktu przerwania w funkcjiPrzykład generatorów:
async/await
jeśli zobaczysz wdrożenie
async/await
, zobaczysz, żegenerator functions & promises
są używane doasync/await
pracyproszę zauważyć, że wszelkie sugestie są mile widziane
źródło
Zależność między asynchronicznymi wywołaniami javascript.
Kolejny dobry przykład wykorzystania plonu.
źródło
Zanim dowiesz się o wydajności, musisz wiedzieć o generatorach. Generatory są tworzone przy użyciu
function*
składni. Funkcje generatora nie wykonują kodu, ale zwracają typ iteratora zwany generatorem. Gdy wartość jest podana za pomocąnext
metody, funkcja generatora działa, dopóki nie natrafi na słowo kluczowe wydajności. Użycieyield
zwraca obiekt zawierający dwie wartości, jedna jest wartością, a druga jest zakończona (boolean). Wartością może być tablica, obiekt itp.źródło
Prosty przykład:
źródło
Próbuję również zrozumieć słowo kluczowe wydajności. W oparciu o moje obecne rozumienie, w generatorze słowo kluczowe wydajności działa jak przełącznik kontekstowy procesora. Po uruchomieniu instrukcji dochodu wszystkie stany (na przykład zmienne lokalne) są zapisywane.
Poza tym obiekt wywołujący zostanie zwrócony bezpośrednio do obiektu wywołującego, na przykład {wartość: 0, done: false}. Program wywołujący może użyć tego obiektu wynikowego, aby zdecydować, czy „obudzić” generator ponownie, wywołując next () (wywołanie next () ma na celu iterację wykonania).
Inną ważną rzeczą jest to, że może ustawić wartość zmiennej lokalnej. Tę wartość może przekazać osoba wywołująca „next ()” podczas „budzenia” generatora. na przykład it.next ('valueToPass'), na przykład: „resultValue = return slowQuery (1);” Podobnie jak w przypadku budzenia następnego wykonania, program wywołujący może wstrzyknąć do wykonania jakiś wynik (wstrzyknąć go do zmiennej lokalnej). Zatem dla tego wykonania istnieją dwa rodzaje stanów:
kontekst zapisany w ostatnim wykonaniu.
Wprowadzane wartości przez wyzwalacz tego wykonania.
Dzięki tej funkcji generator może uporządkować wiele operacji asynchronicznych. Wynik pierwszego zapytania asynchronicznego zostanie przekazany do drugiego poprzez ustawienie zmiennej lokalnej (resultValue w powyższym przykładzie). Drugie zapytanie asynchroniczne może zostać wyzwolone tylko przez odpowiedź pierwszego zapytania asynchronicznego. Następnie drugie zapytanie asynchroniczne może sprawdzić wartość zmiennej lokalnej, aby zdecydować o kolejnych krokach, ponieważ zmienna lokalna jest wartością wstrzykniętą z odpowiedzi na pierwsze zapytanie.
Trudności związane z zapytaniami asynchronicznymi są następujące:
piekło zwrotne
tracą kontekst, chyba że przekażą je jako parametry w wywołaniu zwrotnym.
Wydajność i generator mogą pomóc w obu przypadkach.
Bez wydajności i generatora uporządkowanie wielu zapytań asynchronicznych wymaga zagnieżdżonego wywołania zwrotnego z parametrami jako kontekstem, co nie jest łatwe do odczytania i utrzymania.
Poniżej znajduje się przykładowy łańcuch zapytań asynchronicznych działający z nodejs:
Poniżej znajduje się bieżący wynik:
+++++++++++ start +++++++++++
zapytanie1 0
+++++++++++ end +++++++++++
zapytanie2 1
zapytanie4 0
Poniższy wzorzec stanu może zrobić podobnie dla powyższego przykładu:
Oto wynik działania:
+++++++++++ start +++++++++++
zapytanie1 0
+++++++++++ end +++++++++++
zapytanie2 1
zapytanie4 0
źródło
nie zapomnij o bardzo pomocnej składni „x generatora”, aby przejść przez generator. W ogóle nie trzeba używać funkcji next ().
źródło