Generatorfunktioner i JavaScript

Generatorfunktioner i JavaScript

I denne artikel vil vi forklare generatorfunktioner i JavaScript.

YouTube Video

Generatorfunktioner i JavaScript

JavaScript-generatorfunktioner er specielle funktioner, der adskiller sig fra almindelige funktioner, fordi de kan udføre doven eksekvering og pause og genoptage. Ved at forstå generatorfunktioner kan du effektivt håndtere asynkrone operationer og sekventiel behandling af store mængder data. Her vil vi give en detaljeret forklaring på, hvordan generatorfunktioner fungerer, hvordan de bruges, og praktiske anvendelsesmuligheder.

Hvad er generatorfunktioner?

En generatorfunktion defineres med function* (en funktion med en stjerne), og i modsætning til almindelige funktioner kan den stoppe eksekveringen midtvejs og genoptage den, mens dens tilstand bevares. Generatorfunktioner muliggør "doven eksekvering" og returnerer resultater trinvis, hvilket giver mulighed for effektiv hukommelsesstyring og sekventiel behandling.

Syntaks

1function* generatorFunction() {
2    yield 'First value';
3    yield 'Second value';
4    return 'Done';
5}

På denne måde kan en generatorfunktion have flere yield-udtryk og bruge yield til at stoppe eksekveringen midlertidigt. Når en generatorfunktion kaldes, eksekveres funktionens krop ikke med det samme, og et generatorobjekt returneres. Du kan kalde next()-metoden på dette objekt for at genoptage funktionen fra det punkt, hvor den blev stoppet.

Grundlæggende brug af generatorfunktioner

Lad os derefter se på et grundlæggende eksempel på brug af generatorfunktioner.

 1function* simpleGenerator() {
 2    yield 1;
 3    yield 2;
 4    yield 3;
 5}
 6
 7const gen = simpleGenerator();
 8
 9console.log(gen.next()); // { value: 1, done: false }
10console.log(gen.next()); // { value: 2, done: false }
11console.log(gen.next()); // { value: 3, done: false }
12console.log(gen.next()); // { value: undefined, done: true }

En vigtig ting at bemærke her er, at generatoren returnerer værdier hver gang med yield, og så længe egenskaben done er false, betyder det, at der er flere værdier på vej. Det sidste kald til next() returnerer done: true, hvilket indikerer, at generatoren er afsluttet.

Nøgleordet yield og midlertidig pausering af værdier

yield er et nøgleord, der angiver et punkt for pause inden for en generatorfunktion. Værdien til højre for yield returneres, når next() kaldes. Derudover muliggør yield tovejskommunikation. Med andre ord, når en værdi sendes som et argument til next()-metoden, bliver denne værdi sendt til generatorfunktionen.

 1function* generatorWithYield() {
 2    const value1 = yield 'First yield';
 3    console.log('Received value:', value1);
 4    const value2 = yield 'Second yield';
 5    console.log('Received value:', value2);
 6}
 7
 8const gen = generatorWithYield();
 9
10console.log(gen.next());        // { value: 'First yield', done: false }
11console.log(gen.next('Apple')); // Received value: Apple
12                                // { value: 'Second yield', done: false }
13console.log(gen.next('Banana'));// Received value: Banana
14                                // { value: undefined, done: true }

I dette eksempel sender kaldet next('Apple') værdien 'Apple' til generatorfunktionen, hvor den bruges inde i funktionen.

Håndtering af generatorens tilstand

Generatorer kan bevare deres eksekveringstilstand, hvilket muliggør en kortfattet repræsentation af lange løkker eller sekventiel behandling. Det følgende eksempel demonstrerer en generator, der producerer tal uendeligt.

 1function* infiniteGenerator() {
 2    let i = 0;
 3    while (true) {
 4        yield i++;
 5        if (i > 10) {
 6            break;
 7        }
 8    }
 9}
10
11const gen = infiniteGenerator();
12
13console.log(gen.next().value); // 0
14console.log(gen.next().value); // 1
15console.log(gen.next().value); // 2
16// Continues...

Denne generator producerer kontinuerligt tal ved hjælp af en while(true)-løkke, hvilket giver dig mulighed for at hente værdier efter behov. Dette muliggør effektiv behandling af store datasæt.

Anvendelser af generatorfunktioner

Generatorfunktioner er velegnede til at udføre flere processer sekventielt. For eksempel er de nyttige til sekventiel behandling af API-forespørgsler eller til at opdele og behandle store filer.

1function* apiRequestGenerator() {
2    yield fetch('https://codesparklab.com/json/example1.json');
3    yield fetch('https://codesparklab.com/json/example2.json');
4    yield fetch('https://codesparklab.com/json/example3.json');
5}

Derfor er generatorer, som kan bruges til asynkron behandling, særdeles fordelagtige for effektiv sekventiel datahåndtering.

Asynkrone generatorer

Asynkrone generatorer, introduceret i ES2018, gør det muligt at returnere asynkrone værdier sekventielt ved at kombinere async og yield. Dette gør det muligt at skrive asynkron behandling kortfattet i kombination med await.

Syntaks

 1async function* asyncGenerator() {
 2    yield await Promise.resolve(1);
 3    yield await Promise.resolve(2);
 4    yield await Promise.resolve(3);
 5}
 6
 7const gen = asyncGenerator();
 8
 9(async () => {
10    for await (const value of gen) {
11        console.log(value); // 1, 2, 3
12    }
13})();

Asynkrone generatorer kan hente værdier sekventielt ved hjælp af en for await...of-løkke. Dette mønster er særligt nyttigt, når der arbejdes med asynkrone datastrømme.

Praktisk eksempel: Forenkling af asynkron behandling med generatorer

Generatorfunktioner bruges også til at forenkle flowet af asynkron behandling. For eksempel, ved at kombinere yield og Promise som vist nedenfor, kan du skrive asynkrone operationer, så de fremstår synkrone.

 1function* asyncFlow() {
 2    const data1 = yield fetch('https://codesparklab.com/json/example1.json');
 3    console.log(data1);
 4    const data2 = yield fetch('https://codesparklab.com/json/example2.json');
 5    console.log(data2);
 6}
 7
 8const gen = asyncFlow();
 9
10function handleAsync(generator) {
11    const next = (promise) => {
12        promise.then((result) => {
13        const { value, done } = generator.next(result);
14        if (!done) {
15            next(value);
16        }
17        });
18    };
19
20    next(generator.next().value);
21}
22
23handleAsync(gen);

Denne kode foretager sekventielle API-forespørgsler ved hjælp af en generator og behandler resultaterne.

Sammendrag

Generatorfunktioner er en af JavaScripts kraftfulde funktioner, der har evnen til at pause og genoptage udførelsen af en funktion. Dette muliggør sekventiel behandling, asynkron behandling og effektiv manipulation af store datasæt. At forstå generatorer er et vigtigt skridt i at mestre avancerede teknikker i JavaScript.

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