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.