Generatorfunksjoner i TypeScript

Generatorfunksjoner i TypeScript

Denne artikkelen forklarer generatorfunksjoner i TypeScript.

Du kan lære alt fra det grunnleggende om hvordan du bruker generatorfunksjoner til avanserte eksempler kombinert med asynkron behandling, sammen med kodeeksempler.

YouTube Video

Generatorfunksjoner

Generatorfunksjoner i TypeScript gir lignende funksjonalitet som JavaScript sine generatorfunksjoner. Generatorfunksjoner defineres ved bruk av function* (en funksjonserklæring med en stjerne) og er spesielle funksjoner som kan pause og gjenoppta kjøringen, i motsetning til vanlige funksjoner.

Når en generatorfunksjon blir kalt, returneres en iterator, som genererer verdier én om gangen gjennom denne iteratoren, og du kan pause utføringen ved hjelp av nøkkelordet yield eller sende verdier inn fra utsiden.

Grunnleggende syntaks for generatorfunksjoner

 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)
  • Definer en generatorfunksjon med function* myGenerator().
  • Nøkkelordet yield pauser funksjonskjøringen samtidig som det returnerer en verdi.
  • Hver gang next()-metoden kalles, gjenopptas kjøringen av generatorfunksjonen og går videre til neste yield.

next() returnerer et objekt som inneholder neste verdi og en done-egenskap. Når done er true, indikerer det at alle verdier er generert, og at generatorens prosessering er fullført.

Bruksområder for generatorfunksjoner

Bruk av generatorfunksjoner gjør det enkelt å representere sekvensiell prosessering. I følgende eksempel oppretter vi en generatorfunksjon som genererer en sekvens av tall.

 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 eksempelet genererer sequenceGenerator en uendelig voksende sekvens av tall. Bruk yield for å returnere verdier i hvert trinn, og generer neste verdi ved påfølgende kall.

Overføre verdier til next

next()-metoden kan motta en verdi som kan sendes inn i generatorfunksjonen.

 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 eksempelet sender next(5) og next(10) sine respektive verdier inn i generatorfunksjonen, og yield num1 + num2 returnerer summen av dem.

return og throw

  • return(value) kan avslutte generatoren og returnere den spesifiserte verdien.
  • throw(error) kan kaste et unntak inne i generatoren, noe som brukes til å håndtere unntak innenfor 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 eksempelet brukes throw-metoden til å generere en feil inne i generatoren, og den feilen blir håndtert innenfor generatoren.

Type-definisjon i TypeScript

Typedefinisjonen av en generatorfunksjon kan spesifiseres 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 angir typer i formen Generator<YieldType, ReturnType, NextType>.
    • YieldType er typen av verdien returnert av yield.
    • ReturnType er typen av verdien returnert av return.
    • NextType er typen av verdien sendt til next().

I det følgende eksempelet er spesifikke typer angitt for å bruke generatoren trygt 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å brukes til asynkron behandling. For eksempel kan du bruke yield til å vente på resultatene av asynkrone operasjoner mens du fortsetter med sekvensiell behandling. Men i TypeScript eller JavaScript brukes async/await oftere.

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, selv om du kan behandle asynkrone operasjoner sekvensielt med generatorer, brukes de ikke ofte til asynkron behandling fordi Promises og async/await er mer praktiske.

Sammendrag

  • Generatorfunksjoner er spesialfunksjoner definert med function* som kan returnere verdier med yield mens utførelsen av funksjonen settes på pause.
  • Bruk next() for å fortsette generatoren og motta verdier. I tillegg kan du sende verdier inn i generatoren ved å bruke next(value).
  • Du kan bruke return() og throw() for å avslutte generatorfunksjoner eller håndtere feil.
  • Når du bruker generatorer i TypeScript, kan du bruke typedefinisjoner for å skrive typesikker kode.

Generatorer er kraftige verktøy som lar deg fleksibelt kontrollere iterasjon.

Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.

YouTube Video