Generatorfunktioner i TypeScript
Den här artikeln förklarar generatorfunktioner i TypeScript.
Du kan lära dig allt från grunderna i hur man använder generatorfunktioner till avancerade exempel kombinerade med asynkron bearbetning, tillsammans med kodexempel.
YouTube Video
Generatorfunktioner
Generatorfunktioner i TypeScript erbjuder liknande funktionalitet som JavaScripts generatorfunktioner. Generatorfunktioner definieras med function*
(en funktionsdeklaration med en asterisk) och är speciella funktioner som kan pausa och återuppta exekvering till skillnad från vanliga funktioner.
När en generatorfunktion anropas returneras en iterator som genererar värden ett i taget via denna iterator, och du kan pausa exekveringen med nyckelordet yield
eller skicka värden utifrån.
Grundläggande syntax för 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)
- Definiera en generatorfunktion med
function* myGenerator()
. - Nyckelordet
yield
pausar funktionens exekvering samtidigt som det returnerar ett värde. - Varje gång metoden
next()
anropas återupptas exekveringen av generatorfunktionen och fortsätter till nästayield
.
next()
returnerar ett objekt som innehåller nästa värde och en done
-egenskap. När done
är true
indikerar det att alla värden har genererats och att generatorns process är slutförd.
Användningsområden för generatorfunktioner
Att använda generatorfunktioner möjliggör en enkel representation av sekventiell bearbetning. I följande exempel skapar vi en generatorfunktion som genererar en sekvens av nummer.
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 detta exempel genererar
sequenceGenerator
en obestämt ökande sekvens av nummer. Användyield
för att returnera värden vid varje steg och generera nästa värde vid efterföljande anrop.
Skicka värden till next
Metoden next()
kan ta emot ett värde som kan skickas in 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 detta exempel skickar
next(5)
ochnext(10)
sina respektive värden till generatorfunktionen, ochyield num1 + num2
returnerar deras summa.
return
och throw
return(value)
kan avsluta generatorn och returnera det angivna värdet.throw(error)
kan kasta ett undantag i generatorn, som används för att hantera undantag inom generatorn.
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 detta exempel används
throw
-metoden för att generera ett fel i generatorn, och detta fel fångas inom generatorn.
Typdefinition i TypeScript
Typdefinitionen för en generatorfunktion kan anges i följande format.
1// Generator<YieldType, ReturnType, NextType>
2function* myGenerator(): Generator<number, void, unknown> {
3 yield 1;
4 yield 2;
5 yield 3;
6}
- Du anger typer i formen
Generator<YieldType, ReturnType, NextType>
.YieldType
är typen av värdet som returneras avyield
.ReturnType
är typen av värdet som returneras avreturn
.NextType
är typen av värdet som skickas tillnext()
.
I följande exempel anges specifika typer för att använda generatorn säkert 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 och Asynkron Bearbetning
Generatorer kan också användas för asynkron bearbetning. Du kan till exempel använda yield
för att vänta på resultat från asynkrona operationer medan du fortsätter med sekventiell bearbetning. Men i TypeScript eller JavaScript används async/await
oftare.
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}
Även om du kan bearbeta asynkrona operationer sekventiellt med generatorer används de inte ofta för asynkron bearbetning eftersom Promises och async
/await
är mer praktiska.
Sammanfattning
- Generatorfunktioner är speciella funktioner definierade med
function*
som kan returnera värden medyield
medan funktionen pausar körningen. - Använd
next()
för att återuppta generatorn och ta emot värden. Dessutom kan du skicka värden till generatorn med hjälp avnext(value)
. - Du kan använda
return()
ochthrow()
för att avsluta generatorfunktioner eller hantera fel. - När du använder generatorer i TypeScript kan du använda typdefinitioner för att skriva typesäker kod.
Generatorer är kraftfulla verktyg som låter dig flexibelt styra iteration.
Du kan följa med i artikeln ovan med hjälp av Visual Studio Code på vår YouTube-kanal. Vänligen kolla även in YouTube-kanalen.