2.1 Składnia generatorów
Generatory w JavaScript to specjalne funkcje, które pozwalają zarządzać wykonaniem kodu. Mogą one wstrzymywać swoje wykonanie i wznawiać je później, co czyni je potężnym narzędziem do pracy z kodem asynchronicznym, iteratorami i innymi skomplikowanymi zadaniami.
Generatory definiuje się za pomocą funkcji function*
(zauważ gwiazdkę).
Wewnątrz generatora używamy operatora yield
do wstrzymania wykonania i zwrócenia wartości.
Definicja generatora:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
Tworzenie obiektu generatora
Wywołanie generatora nie wykonuje jego ciała od razu. Zamiast tego zwraca on obiekt generatora, który można wykorzystać do iteracji po wartościach:
const gen = generatorFunction();
2.2 Użycie generatorów
Metoda next()
Metoda next()
służy do wznawiania wykonania generatora do następnego operatora yield
.
Zwraca obiekt z dwoma właściwościami:
value
: wartość zwrócona przez operatoryield
done
: wartość logiczna wskazująca, czy generator zakończył działanie (true
) czy nie (false
)
Przykład użycia metody next():
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
Iteracja po generatorze
Generatory mogą być używane z pętlą for...of
do iteracji po wartościach.
Przykład iteracji po generatorze:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
for (const value of gen) {
console.log(value);
}
// Wypisze: 1
// Wypisze: 2
// Wypisze: 3
Przykład zwracania wartości
Generatory mogą zwracać wartość za pomocą operatora return
:
function* generatorFunction() {
yield 1;
yield 2;
return 3;
yield 4; // Ten yield nigdy nie zostanie wykonany
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: true }
console.log(gen.next()); // { value: undefined, done: true }
2.3 Skomplikowane użycie generatorów
Interakcja z generatorem
Metoda next()
może przyjmować argument, który jest przekazywany do generatora i może być wykorzystany wewnątrz niego.
Przykład przekazywania wartości do generatora:
function* generatorFunction() {
const value1 = yield 1;
const value2 = yield value1 + 2;
yield value2 + 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next(10)); // { value: 12, done: false }
console.log(gen.next(20)); // { value: 23, done: false }
console.log(gen.next()); // { value: undefined, done: true }
Obsługa błędów
Generatory pozwalają na obsługę błędów przy użyciu bloku try...catch
.
Przykład obsługi błędów:
function* generatorFunction() {
try {
yield 1;
yield 2;
} catch (error) {
console.log('Wykryty błąd:', error);
}
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.throw(new Error('Coś poszło nie tak'))); // Wykryty błąd: Error: Coś poszło nie tak
// { value: undefined, done: true }
Przykład generatora do tworzenia nieskończonej sekwencji
Generatory mogą być używane do tworzenia nieskończonych sekwencji wartości:
function* infiniteSequence() {
let i = 0;
while (true) {
yield i++;
}
}
const gen = infiniteSequence();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
// i tak dalej
2.4 Przykłady praktycznego zastosowania
Przykład 1: Generator do iteracji po obiekcie
function* objectEntries(obj) {
const keys = Object.keys(obj);
for (const key of keys) {
yield [key, obj[key]];
}
}
const obj = { a: 1, b: 2, c: 3 };
const gen = objectEntries(obj);
for (const [key, value] of gen) {
console.log(`${key}: ${value}`);
}
// Wypisze:
// a: 1
// b: 2
// c: 3
Przykład 2: Generator do implementacji prostego iteratora
const myIterable = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
};
for (const value of myIterable) {
console.log(value);
}
// Wypisze: 1
// Wypisze: 2
// Wypisze: 3
Generatory w JavaScript to potężne narzędzie do zarządzania wykonaniem kodu, tworzenia iteratorów i pracy z operacjami asynchronicznymi. Zrozumienie składni i użycia generatorów pomaga tworzyć bardziej elastyczny i czytelny kod, zwłaszcza przy pracy z sekwencjami danych i zadaniami asynchronicznymi.
GO TO FULL VERSION