Generatory są funkcjami, które mogą być zakończone i później ponownie wprowadzone. Ich kontekst (wiązania zmiennych) zostanie zachowany przy ponownym wejściu.
Generatory w JavaScript — szczególnie w połączeniu z obietnicami — są bardzo potężnym narzędziem do programowania asynchronicznego, ponieważ łagodzą — jeśli nie całkowicie eliminują — problemy z wywołaniami zwrotnymi, takie jak piekło wywołań zwrotnych i odwrócenie kontroli. Jednak jeszcze prostsze rozwiązanie tych problemów można osiągnąć za pomocą funkcji async.
Wywołanie funkcji generatora nie powoduje natychmiastowego wykonania jej ciała; zamiast tego zwracany jest obiekt iteratora dla tej funkcji. Kiedy wywoływana jest metoda next()
iteratora, ciało funkcji generatora jest wykonywane aż do pierwszego yield
wyrażenia, które określa wartość, która ma być zwrócona z iteratora lub, z yield*
, deleguje do innej funkcji generatora. Metoda next()
zwraca obiekt z właściwością value
zawierającą zwróconą wartość i właściwością done
, która wskazuje, czy generator zwrócił ostatnią wartość, jako boolean. Wywołanie metody next()
z argumentem spowoduje wznowienie wykonywania funkcji generatora, zastępując wyrażenie yield
, w którym wykonanie zostało wstrzymane, argumentem z next()
.
Konstrukcja return
w generatorze, po wykonaniu, spowoduje zakończenie działania generatora (tzn. właściwość done
zwracanego przez nią obiektu zostanie ustawiona na true
). Jeśli zwrócona zostanie wartość, zostanie ona ustawiona jako właściwość value
obiektu zwróconego przez generator.
Podobnie jak instrukcja return
, błąd rzucony wewnątrz generatora spowoduje, że generator zostanie zakończony — chyba że zostanie złapany w ciele generatora.
Kiedy generator zostanie zakończony, kolejne wywołania next()
nie wykonają żadnego kodu tego generatora, tylko zwrócą obiekt w tej postaci: {value: undefined, done: true}
.