Funkcje Generatora w TypeScript

Funkcje Generatora w TypeScript

Ten artykuł wyjaśnia funkcje generatora w TypeScript.

Możesz nauczyć się wszystkiego, począwszy od podstaw korzystania z funkcji generatorowych, aż po zaawansowane przykłady połączone z przetwarzaniem asynchronicznym, wraz z fragmentami kodu.

YouTube Video

Funkcje Generatora

Funkcje generatora w TypeScript oferują podobną funkcjonalność jak funkcje generatora w JavaScript. Funkcje generatora definiuje się za pomocą function* (deklaracja funkcji z gwiazdką) i są to specjalne funkcje, które mogą wstrzymywać i wznawiać wykonanie, w przeciwieństwie do zwykłych funkcji.

Kiedy wywoływana jest funkcja generatora, zwracany jest iterator, który generuje wartości jedna po drugiej za pomocą iteratora, a wykonanie można wstrzymać za pomocą słowa kluczowego yield lub przesyłać wartości z zewnątrz.

Podstawowa składnia funkcji generatora

 1function* myGenerator(): Generator<number, void, unknown> {
 2    yield 1;
 3    yield 2;
 4    yield 3;
 5}
 6
 7const gen = myGenerator();
 8
 9console.log(gen.next().value); // 1
10console.log(gen.next().value); // 2
11console.log(gen.next().value); // 3
12console.log(gen.next().done);  // true (Iteration finished)
  • Zdefiniuj funkcję generatora za pomocą function* myGenerator().
  • Słowo kluczowe yield wstrzymuje wykonanie funkcji, zwracając jednocześnie wartość.
  • Za każdym razem, gdy wywoływana jest metoda next(), wykonanie funkcji generatora jest wznawiane i przechodzi do następnego yield.

next() zwraca obiekt zawierający następną wartość oraz właściwość done. Kiedy done jest równe true, oznacza to, że wszystkie wartości zostały wygenerowane i przetwarzanie generatora zostało zakończone.

Zastosowania funkcji generatora

Korzystanie z funkcji generatora umożliwia łatwe przedstawienie przetwarzania sekwencyjnego. W poniższym przykładzie tworzymy funkcję generatora, która generuje sekwencję liczb.

 1function* sequenceGenerator(start: number = 0, step: number = 1) {
 2    let current = start;
 3    while (true) {
 4        yield current;
 5        current += step;
 6    }
 7}
 8
 9const seq = sequenceGenerator(1, 2);
10
11console.log(seq.next().value); // 1
12console.log(seq.next().value); // 3
13console.log(seq.next().value); // 5
  • W tym przykładzie sequenceGenerator generuje nieskończenie rosnącą sekwencję liczb. Użyj yield, aby zwrócić wartości na każdym kroku, i generuj kolejną wartość w kolejnych wywołaniach.

Przekazywanie wartości do next

Metoda next() może otrzymać wartość, która może zostać przesłana do funkcji generatora.

 1function* adder() {
 2    const num1 = yield;
 3    const num2 = yield;
 4    yield num1 + num2;
 5}
 6
 7const addGen = adder();
 8addGen.next();          // Initialization
 9addGen.next(5);         // Set 5 to num1
10const result = addGen.next(10).value; // Set 10 to num2 and get result
11console.log(result);    // 15
  • W tym przykładzie next(5) i next(10) przesyłają swoje wartości do funkcji generatora, a yield num1 + num2 zwraca ich sumę.

return i throw

  • return(value) może zakończyć generator i zwrócić określoną wartość.
  • throw(error) może wyrzucić wyjątek wewnątrz generatora, stosowany do obsługi wyjątków w obrębie generatora.
 1function* testGenerator() {
 2    try {
 3        yield 1;
 4        yield 2;
 5    } catch (e) {
 6        console.error("Error caught:", e);
 7    }
 8}
 9
10const gen = testGenerator();
11console.log(gen.next().value); // 1
12gen.throw(new Error("An error occurred!")); // Error caught: An error occurred!
  • W tym przykładzie metoda throw jest używana do wygenerowania błędu wewnątrz generatora, a ten błąd jest przechwytywany w obrębie generatora.

Definicja typów w TypeScript

Definicję typu funkcji generatora można określić w następującym formacie.

1// Generator<YieldType, ReturnType, NextType>
2function* myGenerator(): Generator<number, void, unknown> {
3    yield 1;
4    yield 2;
5    yield 3;
6}
  • Określasz typy w formie Generator<YieldType, ReturnType, NextType>.
    • YieldType to typ wartości zwracanej przez yield.
    • ReturnType to typ wartości zwracanej przez return.
    • NextType to typ wartości przekazywanej do next().

W poniższym przykładzie określono konkretne typy, aby bezpiecznie korzystać z generatora z zastosowaniem typów.

 1function* numberGenerator(): Generator<number, void, number> {
 2    const num1 = yield 1;
 3    const num2 = yield num1 + 2;
 4    yield num2 + 3;
 5}
 6
 7const gen = numberGenerator();
 8
 9console.log(gen.next().value);   // 1
10console.log(gen.next(10).value); // 12 (10 + 2)
11console.log(gen.next(20).value); // 23 (20 + 3)

Generatory i przetwarzanie asynchroniczne

Generatory mogą być również wykorzystywane do przetwarzania asynchronicznego. Na przykład możesz użyć yield, aby poczekać na wyniki operacji asynchronicznych, jednocześnie kontynuując przetwarzanie sekwencyjne. Jednak w TypeScript lub JavaScript częściej stosuje się async/await.

1function* asyncTask() {
2    const result1 = yield fetch("https://codesparklab.com/json/example1.json");
3    console.log(result1);
4
5    const result2 = yield fetch("https://codesparklab.com/json/example2.json");
6    console.log(result2);
7}

Chociaż możesz przetwarzać operacje asynchroniczne sekwencyjnie za pomocą generatorów, nie są one powszechnie używane w przetwarzaniu asynchronicznym, ponieważ Promisy i async/await są bardziej wygodne.

Podsumowanie

  • Funkcje generatorowe to specjalne funkcje zdefiniowane za pomocą function*, które mogą zwracać wartości za pomocą yield, jednocześnie wstrzymując wykonywanie funkcji.
  • Użyj next(), aby wznowić generator i otrzymać wartości. Dodatkowo możesz przesyłać wartości do generatora, używając next(value).
  • Możesz używać return() i throw(), aby zakończyć funkcje generatorowe lub obsłużyć błędy.
  • Podczas korzystania z generatorów w TypeScript możesz używać definicji typów, aby pisać kod bezpieczny typowo.

Generatory to potężne narzędzia, które pozwalają elastycznie kontrolować iterację.

Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.

YouTube Video