Generator-funksjoner i JavaScript

Generator-funksjoner i JavaScript

I denne artikkelen skal vi forklare generator-funksjoner i JavaScript.

YouTube Video

Generator-funksjoner i JavaScript

JavaScript generator-funksjoner er spesielle funksjoner som skiller seg fra vanlige funksjoner ved at de kan utføre lazy execution og pause og gjenoppta. Ved å forstå generator-funksjoner kan du effektivt håndtere asynkrone operasjoner og sekvensiell prosessering av store datamengder. Her vil vi gi en detaljert forklaring på hvordan generator-funksjoner fungerer, hvordan de brukes, og praktiske bruksområder.

Hva er generator-funksjoner?

En generator-funksjon defineres med function* (en funksjonsdefinisjon med en stjerne), og i motsetning til vanlige funksjoner kan den pause kjøringen midtveis og gjenoppta mens den beholder sin tilstand. Generator-funksjoner tillater "lazy execution" og returnerer resultater gradvis, noe som gir effektiv minnehåndtering og sekvensiell prosessering.

Syntaks

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

På denne måten kan en generator-funksjon ha flere yield-uttrykk og bruke yield for å pause kjøringen. Når en generator-funksjon kalles, blir ikke kroppens funksjon utført umiddelbart, og et generator-objekt returneres. Du kan kalle metoden next() på dette objektet for å gjenoppta funksjonen fra punktet der den ble pauset.

Grunnleggende bruk av generator-funksjoner

La oss se på et grunnleggende eksempel på bruk av generator-funksjoner.

 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 }

Et viktig poeng her er at generatoren returnerer verdier hver gang med yield, og så lenge done-egenskapen er false, indikerer det at flere verdier vil komme. Den siste kallet til next() returnerer done: true, noe som indikerer at generatoren er fullført.

yield-nøkkelordet og pauser verdier

yield er et nøkkelord som indikerer et pausepunkt i en generator-funksjon. Verdien til høyre for yield returneres når next() kalles. I tillegg tillater yield toveiskommunikasjon. Med andre ord, ved å sende en verdi som et argument til metoden next(), sendes den verdien til generator-funksjonen.

 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 eksemplet sender kallet next('Apple') verdien 'Apple' til generator-funksjonen, der den brukes i funksjonen.

Håndtering av generatorens tilstand

Generatorer kan opprettholde sin kjøringsstatus, noe som muliggjør en konsis representasjon av lange løkker eller sekvensiell prosessering. Følgende eksempel demonstrerer en generator som produserer tall på ubestemt tid.

 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 generatoren produserer tall kontinuerlig ved hjelp av en while(true)-løkke, som lar deg hente verdier etter behov. Dette muliggjør effektiv behandling av store datasett.

Bruksområder for Generatorfunksjoner

Generatorfunksjoner egner seg for å kjøre flere prosesser sekvensielt. For eksempel er de nyttige for å behandle API-forespørsler sekvensielt eller dele opp 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}

Generatore, som kan brukes til asynkron behandling, er derfor svært nyttige for effektiv sekvensiell håndtering av data.

Asynkrone Generatorer

Asynkrone generatorer, introdusert i ES2018, lar deg returnere asynkrone verdier sekvensielt ved å kombinere async og yield. Dette gjør det mulig å skrive asynkron behandling konsist ved å kombinere det 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 verdier sekvensielt ved å bruke en for await...of-løkke. Dette mønsteret er spesielt nyttig når du håndterer asynkrone datastrømmer.

Praktisk Eksempel: Forenkling av Asynkron Behandling med Generatorer

Generatorfunksjoner brukes også til å forenkle flyten av asynkron behandling. For eksempel kan du ved å kombinere yield og Promise, som vist nedenfor, skrive asynkrone operasjoner slik at de fremstår som 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 koden utfører API-forespørsler sekvensielt ved hjelp av en generator og behandler resultatene.

Sammendrag

Generatorfunksjoner er en av JavaScripts kraftige funksjoner, og har evnen til å pause og gjenoppta kjøringen av en funksjon. Dette muliggjør sekvensiell behandling, asynkron behandling og effektiv håndtering av store datasett. Å forstå generatorer er et viktig steg for å mestre avanserte teknikker i JavaScript.

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