function*
Deklaruje generator: funkcję, która oddaje kolejne wartości przez yield i wstrzymuje się między nimi.
- Zwraca
- Wywołanie funkcji generatora zwraca obiekt generatora, który jest jednocześnie iteratorem i obiektem iterowalnym.
Przykład
#function* lessonSteps() {
yield 'Wideo'
yield 'Teoria'
yield 'Quiz'
}
const steps = lessonSteps()
console.log(steps.next())
console.log(steps.next())
console.log(steps.next())
console.log(steps.next())Definicja i zastosowanie
#Funkcja zapisana jako function* jest generatorem. Jej wywołanie nie uruchamia kodu od razu, tylko zwraca obiekt generatora. Kod rusza dopiero po wywołaniu next() i działa do najbliższego yield, które oddaje wartość i zatrzymuje funkcję w tym miejscu. Kolejne next() wznawia pracę dokładnie tam, gdzie się zatrzymała.
Każde next() zwraca obiekt { value, done }. Dopóki generator dochodzi do kolejnych yield, pole done ma wartość false. Gdy funkcja skończy działanie albo trafi na return, dostaniesz done: true. Generator jest obiektem iterowalnym, więc przejdziesz po nim pętlą for...of, rozłożysz spreadem [...gen] albo przekażesz do Array.from().
Generatory liczą wartości leniwie, czyli dopiero wtedy, gdy są potrzebne. Dzięki temu mogą opisywać nawet nieskończone ciągi, np. kolejne identyfikatory, bez zajmowania pamięci. yield* przekazuje dalej wszystkie wartości z innego obiektu iterowalnego, a async function* tworzy generator asynchroniczny, po którym przechodzi się pętlą for await...of.
Składnia
#function* name(params) {
yield value
yield* iterable
return finalValue
}
const generator = name()
generator.next()Więcej przykładów
#function* range(start, end, step = 1) {
for (let i = start; i <= end; i += step) {
yield i
}
}
for (const level of range(1, 3)) {
console.log(`Poziom ${level}`)
}
console.log([...range(0, 20, 5)])function* createIds(prefix) {
let id = 1
while (true) {
yield `${prefix}-${id}`
id++
}
}
const taskIds = createIds('task')
console.log(taskIds.next().value)
console.log(taskIds.next().value)
console.log(taskIds.next().value)Pętla while (true) nie zawiesza programu, bo generator zatrzymuje się na każdym yield i czeka na kolejne wywołanie next().
function* frontend() {
yield 'HTML'
yield 'CSS'
}
function* fullStack() {
yield* frontend()
yield 'JavaScript'
yield* ['Node.js', 'SQL']
}
console.log([...fullStack()])Obsługa przeglądarek
#Szeroko dostępne
Działa we wszystkich nowoczesnych przeglądarkach, także na telefonach. Możesz używać bez obaw.
- Chrome
- Edge
- Firefox
- Safari
Dobre praktyki
#- Po generatorze można przejść tylko raz. Gdy potrzebujesz wartości ponownie, wywołaj funkcję generatora jeszcze raz albo zapisz wyniki w tablicy.
- Wartość z
returnmadone: true, więc pętlafor...ofi spread ją pomijają. Wszystko, co ma trafić do wyniku, oddawaj przezyield. - Nie rozkładaj spreadem ani przez
Array.from()generatora nieskończonego. Pobieraj z niego wartości przeznext()albo przerwij pętlę instrukcjąbreak.
Powiązane hasła
#- Iteratory (Symbol.iterator)Protokół iteracji: obiekt z metodą [Symbol.iterator]() działa z for...of, spreadem i destrukturyzacją.
- for...ofPrzechodzi po kolejnych wartościach obiektu iterowalnego: tablicy, napisu, Map, Set i innych.
- functionDeklaruje nazwaną funkcję: blok kodu z parametrami, który można wywoływać wiele razy i który może zwrócić wynik.
- Spread (...)Składnia spread rozkłada tablicę, napis lub obiekt na pojedyncze elementy: do kopiowania, łączenia i przekazywania argumentów.
- returnKończy działanie funkcji i przekazuje wartość do miejsca, w którym funkcję wywołano.
Widzisz błąd albo brakuje przykładu? Napisz do nas.