Generatorfuncties in TypeScript

Generatorfuncties in TypeScript

Dit artikel legt de generatorfuncties in TypeScript uit.

Je kunt alles leren, van de basis van hoe je generatorfuncties gebruikt tot geavanceerde voorbeelden gecombineerd met asynchrone verwerking, samen met codevoorbeelden.

YouTube Video

Generatorfuncties

Generatorfuncties in TypeScript bieden vergelijkbare functionaliteit als de generatorfuncties in JavaScript. Generatorfuncties worden gedefinieerd met behulp van function* (een functiedeclaratie met een asterisk) en zijn speciale functies die de uitvoering kunnen pauzeren en hervatten, in tegenstelling tot normale functies.

Wanneer een generatorfunctie wordt aangeroepen, wordt een iterator geretourneerd, die waarden één voor één genereert via deze iterator. Je kunt de uitvoering pauzeren met het sleutelwoord yield of waarden van buitenaf doorgeven.

Basis syntaxis van generatorfuncties

 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)
  • Definieer een generatorfunctie met function* myGenerator().
  • Het sleutelwoord yield pauzeert de uitvoering van de functie terwijl het een waarde retourneert.
  • Elke keer dat de methode next() wordt aangeroepen, wordt de uitvoering van de generatorfunctie hervat en gaat deze verder naar de volgende yield.

next() retourneert een object met de volgende waarde en een done eigenschap. Wanneer done true is, geeft dit aan dat alle waarden zijn gegenereerd en dat de verwerking van de generator is voltooid.

Toepassingen van generatorfuncties

Het gebruik van generatorfuncties maakt een eenvoudige representatie van sequentiële verwerking mogelijk. In het volgende voorbeeld maken we een generatorfunctie die een reeks getallen genereert.

 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
  • In dit voorbeeld genereert sequenceGenerator een oneindig toenemende reeks getallen. Gebruik yield om waarden bij elke stap te retourneren en genereer de volgende waarde bij volgende aanroepen.

Waarden doorgeven aan next

De methode next() kan een waarde ontvangen die naar de generatorfunctie kan worden verzonden.

 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
  • In dit voorbeeld sturen next(5) en next(10) hun respectieve waarden naar de generatorfunctie en yield num1 + num2 retourneert hun som.

return en throw

  • return(value) kan de generator beëindigen en de opgegeven waarde retourneren.
  • throw(error) kan een exceptie in de generator werpen, wat handig is voor foutafhandeling binnen de generator.
 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!
  • In dit voorbeeld wordt de throw methode gebruikt om een fout in de generator te genereren, en die fout wordt binnen de generator opgevangen.

Type Definitie in TypeScript

De typedefinitie van een generatorfunctie kan in het volgende formaat worden gespecificeerd.

1// Generator<YieldType, ReturnType, NextType>
2function* myGenerator(): Generator<number, void, unknown> {
3    yield 1;
4    yield 2;
5    yield 3;
6}
  • Je specificeert types in de vorm van Generator<YieldType, ReturnType, NextType>.
    • YieldType is het type van de waarde die door yield wordt geretourneerd.
    • ReturnType is het type van de waarde die door return wordt geretourneerd.
    • NextType is het type van de waarde die aan next() wordt doorgegeven.

In het volgende voorbeeld worden specifieke types gespecificeerd om de generator veilig met types te gebruiken.

 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)

Generatoren en Asynchrone Verwerking

Generatoren kunnen ook worden gebruikt voor asynchrone verwerking. Bijvoorbeeld, je kunt yield gebruiken om te wachten op de resultaten van asynchrone operaties terwijl je doorgaat met sequentiële verwerking. Echter, in TypeScript of JavaScript wordt async/await vaker gebruikt.

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}

Dus, hoewel je met generatoren asynchrone operaties sequentieel kunt verwerken, worden ze niet vaak gebruikt voor asynchrone verwerking omdat Promises en async/await handiger zijn.

Samenvatting

  • Generatorfuncties zijn speciale functies gedefinieerd met function* die waarden kunnen retourneren met yield terwijl de uitvoering van de functie wordt gepauzeerd.
  • Gebruik next() om de generator te hervatten en waarden te ontvangen. Daarnaast kun je waarden naar de generator sturen met behulp van next(value).
  • Je kunt return() en throw() gebruiken om generatorfuncties te beëindigen of fouten af te handelen.
  • Wanneer je generatoren gebruikt in TypeScript, kun je typedefinities gebruiken om type-veilige code te schrijven.

Generatoren zijn krachtige tools die je in staat stellen iteraties flexibel te beheren.

Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.

YouTube Video