Generatorfunktioner i TypeScript

Generatorfunktioner i TypeScript

Denne artikel forklarer generatorfunktioner i TypeScript.

Du kan lære alt fra det grundlæggende i brugen af generatorfunktioner til avancerede eksempler kombineret med asynkron behandling, sammen med kodeeksempler.

YouTube Video

Generatorfunktioner

Generatorfunktioner i TypeScript giver lignende funktionalitet som JavaScripts generatorfunktioner. Generatorfunktioner defineres ved hjælp af function* (en funktionsdeklaration med en stjerne) og er særlige funktioner, der kan pause og genoptage udførslen i modsætning til normale funktioner.

Når en generatorfunktion kaldes, returneres der en iterator, der genererer værdier en ad gangen gennem denne iterator, og man kan pause udførelsen ved hjælp af yield-nøgleordet eller sende værdier udefra.

Grundlæggende syntaks for generatorfunktioner

 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)
  • Definér en generatorfunktion med function* myGenerator().
  • yield-nøgleordet pauser funktionens udførelse, mens det returnerer en værdi.
  • Hver gang next()-metoden kaldes, genoptages udførelsen af generatorfunktionen og fortsætter til den næste yield.

next() returnerer et objekt, der indeholder den næste værdi og en done-egenskab. Når done er true, angiver det, at alle værdier er blevet genereret, og generatorens behandling er fuldført.

Anvendelser af generatorfunktioner

Ved at bruge generatorfunktioner er det nemt at repræsentere sekventiel behandling. I det følgende eksempel opretter vi en generatorfunktion, der genererer en sekvens af tal.

 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
  • I dette eksempel genererer sequenceGenerator en uendeligt stigende sekvens af tal. Brug yield til at returnere værdier ved hvert trin og generere den næste værdi ved efterfølgende kald.

Overfør værdier til next

next()-metoden kan modtage en værdi, som kan sendes ind i generatorfunktionen.

 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
  • I dette eksempel sender next(5) og next(10) deres respektive værdier ind i generatorfunktionen, og yield num1 + num2 returnerer deres sum.

return og throw

  • return(value) kan afslutte generatoren og returnere den angivne værdi.
  • throw(error) kan generere en undtagelse inden i generatoren og bruges til at håndtere undtagelser inden for generatoren.
 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!
  • I dette eksempel bruges throw-metoden til at generere en fejl inde i generatoren, og den fejl opfanges inden for generatoren.

Type Definition i TypeScript

Typedefinitionen for en generatorfunktion kan specificeres i følgende format.

1// Generator<YieldType, ReturnType, NextType>
2function* myGenerator(): Generator<number, void, unknown> {
3    yield 1;
4    yield 2;
5    yield 3;
6}
  • Du angiver typerne i formen Generator<YieldType, ReturnType, NextType>.
    • YieldType er typen af den værdi, der returneres af yield.
    • ReturnType er typen af den værdi, der returneres af return.
    • NextType er typen af den værdi, der sendes til next().

I det følgende eksempel angives specifikke typer for at bruge generatoren sikkert med typer.

 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)

Generatorer og Asynkron Behandling

Generatorer kan også bruges til asynkron behandling. For eksempel kan du bruge yield til at vente på resultaterne af asynkrone operationer, samtidig med at du fortsætter med sekventiel behandling. Men i TypeScript eller JavaScript anvendes async/await mere almindeligt.

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}

Derfor, selvom du kan behandle asynkrone operationer sekventielt med generatorer, bruges de ikke ofte til asynkron behandling, fordi Promises og async/await er mere praktiske.

Sammendrag

  • Generatorfunktioner er specielle funktioner defineret med function*, der kan returnere værdier med yield, mens udførelsen af funktionen sættes på pause.
  • Brug next() til at genoptage generatoren og modtage værdier. Derudover kan du sende værdier ind i generatoren ved hjælp af next(value).
  • Du kan bruge return() og throw() til at afslutte generatorfunktioner eller håndtere fejl.
  • Når du bruger generatorer i TypeScript, kan du anvende typedefinitioner til at skrive typesikker kode.

Generatorer er kraftfulde værktøjer, der giver dig mulighed for fleksibelt at kontrollere iteration.

Du kan følge med i ovenstående artikel ved hjælp af Visual Studio Code på vores YouTube-kanal. Husk også at tjekke YouTube-kanalen.

YouTube Video