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æsteyield
.
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. Brugyield
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)
ognext(10)
deres respektive værdier ind i generatorfunktionen, ogyield 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 afyield
.ReturnType
er typen af den værdi, der returneres afreturn
.NextType
er typen af den værdi, der sendes tilnext()
.
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 medyield
, 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 afnext(value)
. - Du kan bruge
return()
ogthrow()
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.