Mga Generator Function sa JavaScript

Mga Generator Function sa JavaScript

Sa artikulong ito, ipapaliwanag namin ang tungkol sa mga generator function sa JavaScript.

YouTube Video

Mga Generator Function sa JavaScript

Ang mga generator function sa JavaScript ay mga natatanging function na naiiba sa mga karaniwang function dahil maaari nilang isagawa ang tamad na pagtakbo (lazy execution) at pagpahinto at pagpapatuloy. Sa pamamagitan ng pag-unawa sa mga generator function, maaari mong mahusay na pamahalaan ang mga asynchronous na operasyon at ang pagsusunod-sunod na pagproseso ng malaking datos. Dito, magbibigay kami ng detalyadong paliwanag kung paano gumagana ang mga generator function, paano ito gamitin, at mga praktikal na halimbawa ng paggamit.

Ano ang mga Generator Function?

Ang isang generator function ay tinutukoy gamit ang function* (isang function na may asterisko) at, hindi tulad ng mga karaniwang function, maaari itong magpahinto ng pagtakbo sa kalagitnaan at magpatuloy habang pinapanatili ang estado nito. Ang mga generator function ay nagbibigay-daan sa "tamad na pagtakbo" at nagbabalik ng resulta ng unti-unti, na nagbibigay-daan sa mahusay na pamamahala ng memorya at pagsusunod-sunod na pagproseso.

Sintaks

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

Sa ganitong paraan, ang isang generator function ay maaaring magkaroon ng maraming ekspresyon ng yield at gamitin ang yield upang ihinto pansamantala ang pagtakbo nito. Kapag ang isang generator function ay tinawag, ang katawan ng function ay hindi agad tumatakbo, at isang generator object ang naibabalik. Puwede mong tawagin ang next() na paraan sa object na ito upang ipagpatuloy ang function mula sa puntong itinigil ito.

Pangunahing Paggamit ng Mga Generator Function

Susunod, tingnan natin ang isang pangunahing halimbawa ng paggamit ng mga generator function.

 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 }

Isang mahalagang bagay na dapat tandaan dito ay ibinabalik ng generator ang mga halaga tuwing may yield, at hangga't false ang done na ari-arian, nangangahulugan itong mayroong mga natitira pang halaga. Ang huling tawag sa next() ay nagbabalik ng done: true, na nagpapahiwatig na natapos na ang generator.

Ang Salitang Pantukoy na yield at Pagpigil sa Mga Halaga

Ang yield ay isang salitang pantukoy na nagpapahiwatig ng isang puntong pahinto sa loob ng isang generator function. Ang halaga sa kanan ng yield ay naibabalik kapag ang next() ay tinawag. Bukod dito, ang yield ay nagbibigay-daan sa dalawang-direksyong komunikasyon. Sa madaling salita, kapag may ipinasa na halaga bilang argumento sa paraan ng next(), ang halagang iyon ay ipinapadala sa generator function.

 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 }

Sa halimbawang ito, ang tawag na next('Apple') ay nagpapadala ng halagang 'Apple' sa generator function, kung saan ito ginagamit sa loob ng function.

Pamamahala sa Estado ng Generator

Ang mga generator ay maaaring mapanatili ang kanilang estado ng pagtakbo, na nagbibigay-daan sa maikli ngunit epektibong representasyon ng mahahabang loop o pagsusunod-sunod na pagproseso. Ang sumusunod na halimbawa ay nagpapakita ng isang generator na patuloy na gumagawa ng mga numero nang walang hanggan.

 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...

Ang generator na ito ay tuloy-tuloy na gumagawa ng mga numero gamit ang isang while(true) loop, na nagpapahintulot sa iyo na makakuha ng mga halaga kung kinakailangan. Pinapayagan nito ang mahusay na pagpoproseso ng malalaking set ng data.

Mga Aplikasyon ng Generator Functions

Ang mga generator function ay angkop para sa pagpapagana ng maraming proseso nang sunud-sunod. Halimbawa, ang mga ito ay kapaki-pakinabang sa pagpoproseso ng mga API request nang magkakasunod o paghahati-hati at pagpoproseso ng malalaking file.

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}

Kaya, ang mga generator, na maaaring magamit para sa asynchronous na pagpoproseso, ay napakalaking pakinabang para sa mahusay na sunud-sunod na paghawak ng data.

Asynchronous Generator

Asynchronous generator na ipinakilala noong ES2018 ay nagbibigay-daan upang maibalik ang mga asynchronous na halaga nang magkakasunod sa pamamagitan ng pagsasama ng async at yield. Ginagawa nitong posible na maisulat nang maikli ang asynchronous na pagpoproseso sa pagsasama ng await.

Sintaks

 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})();

Ang mga asynchronous generator ay maaaring kumuha ng mga halaga nang sunud-sunod gamit ang isang for await...of loop. Ang pattern na ito ay partikular na kapaki-pakinabang kapag humahawak ng mga asynchronous na data stream.

Praktikal na Halimbawa: Pagpapasimple ng Asynchronous na Pagpoproseso gamit ang Generators

Ang mga generator function ay ginagamit din upang pasimplehin ang daloy ng asynchronous na pagpoproseso. Halimbawa, sa pamamagitan ng pagsasama ng yield at Promise tulad ng ipinapakita sa ibaba, maaari kang magsulat ng mga asynchronous na operasyon na magmumukhang synchronous.

 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);

Ang code na ito ay sunud-sunod na gumagawa ng mga API request gamit ang isang generator at ipoproseso ang mga resulta.

Buod

Ang mga generator function ay isa sa mga makapangyarihang katangian ng JavaScript, may kakayahan na i-pause at muling ipagpatuloy ang pagpapatakbo ng isang function. Pinapayagan nito ang sunud-sunod na pagpoproseso, asynchronous na pagpoproseso, at mahusay na pagmamanipula ng malalaking set ng data. Ang pag-unawa sa mga generator ay isang mahalagang hakbang sa pag-master ng mga advanced na pamamaraan sa JavaScript.

Maaari mong sundan ang artikulo sa itaas gamit ang Visual Studio Code sa aming YouTube channel. Paki-check din ang aming YouTube channel.

YouTube Video