Tentang generator di JavaScript ES6, dan mengapa itu opsional untuk mempelajarinya

Ketika konstruk async / menunggu semakin populer, demikian juga minat pada mekanisme internalnya. Setelah mencari-cari di Internet, mudah untuk mengetahui bahwa async / menunggu didasarkan pada janji-janji yang terkenal, dan generator, yang jauh kurang dikenal dan populer.



Materi, terjemahan yang kami terbitkan hari ini, dikhususkan untuk generator. Yaitu, di sini kita akan berbicara tentang bagaimana mereka bekerja, dan bagaimana mereka, bersama dengan janji-janji, digunakan di dalam perut async / menunggu konstruksi. Penulis artikel ini mengatakan bahwa generator, demi aplikasi praktisnya, tidak perlu dikuasai. Selain itu, ia mencatat bahwa ia berharap pembaca sedikit berpengalaman dalam janji-janji.

Iterator dan Generator


Dalam JavaScript, dimulai dengan rilis standar ES6, beberapa fitur baru telah muncul yang ditujukan untuk menyederhanakan pekerjaan dengan aliran data dan koleksi asinkron. Iterator dan generator termasuk dalam kategori ini.

Fitur penting dari iterator adalah mereka menyediakan sarana untuk mengakses item koleksi satu per satu, sementara memungkinkan Anda untuk melacak pengidentifikasi item saat ini.

function makeIterator(array) {  var nextIndex = 0;  console.log("nextIndex =>", nextIndex);  return {    next: function() {      return nextIndex < array.length        ? { value: array[nextIndex++], done: false }        : { done: true };    }  }; } var it = makeIterator(["simple", "iterator"]); console.log(it.next()); // {value: 'simple, done: false} console.log(it.next()); // {value: 'iterator, done: false} console.log(it.next()); // {done: true} 

Di atas, kita meneruskan fungsi makeIterator() sebuah array kecil yang berisi beberapa elemen, setelah itu kita melewatinya dengan iterator, memanggil metode it.next() . Perhatikan komentar yang menunjukkan hasil yang diperoleh menggunakan iterator.

Sekarang mari kita bicara tentang generator. Generator adalah fungsi yang bekerja seperti pabrik iterator. Pertimbangkan contoh sederhana, dan kemudian bicarakan dua mekanisme yang terkait dengan generator.

 function* sample() { yield "simple"; yield "generator"; } var it = sample(); console.log(it.next()); // {value: 'simple, done: false} console.log(it.next()); // {value: 'generator, done: false} console.log(it.next()); // {value: undefined, done: true} 

Perhatikan tanda bintang dalam deklarasi fungsi. Ini menunjukkan bahwa fungsi ini adalah generator. Juga, lihat kata kunci yield . Ini menjeda eksekusi fungsi dan mengembalikan nilai tertentu. Sebenarnya, kedua fitur ini adalah dua mekanisme yang kita bicarakan di atas:

  • Fungsi generator adalah fungsi yang dideklarasikan menggunakan tanda bintang di sebelah kata kunci function atau di sebelah nama fungsi.
  • Generator iterator dibuat ketika fungsi generator dipanggil.

Secara umum, contoh di atas menunjukkan operasi fungsi pabrik yang menghasilkan iterator.

Sekarang kita sudah menemukan dasar-dasarnya, mari kita bicara tentang hal-hal yang lebih menarik. Iterator dan generator dapat bertukar data dalam dua arah. Yaitu, generator, menggunakan kata kunci yield , dapat mengembalikan nilai ke iterator, namun iterator juga dapat mengirim data ke generator menggunakan metode iterator.next('someValue') . Ini tampilannya.

 function* favBeer() { const reply = yield "What is your favorite type of beer?"; console.log(reply); if (reply !== "ipa") return "No soup for you!"; return "OK, soup."; } { const it = favBeer(); const q = it.next().value; //    console.log(q); const a = it.next("lager").value; //     console.log(a); } // What is your favorite beer? // lager // No soup for you! { const it = favBeer(); const q = it.next().value; //    console.log(q); const a = it.next("ipa").value; //     console.log(a); } // What is your favorite been? // ipa // OK, soup. 

Generator dan Janji


Sekarang kita dapat berbicara tentang bagaimana generator dan janji membentuk dasar dari konstruksi async / menunggu. Bayangkan bahwa alih-alih mengembalikan beberapa nilai menggunakan kata kunci yield , generator mengembalikan janji. Dalam situasi ini, generator dapat dibungkus dalam fungsi yang akan menunggu janji untuk menyelesaikan dan mengembalikan nilai janji ke generator dalam metode .next() , seperti yang ditunjukkan pada contoh sebelumnya. Ada perpustakaan populer, co , yang melakukan tindakan seperti itu. Ini terlihat seperti ini:

 co(function* doStuff(){ var result - yield someAsyncMethod(); var another = yield anotherAsyncFunction(); }); 

Ringkasan


Menurut penulis bahan ini, pengembang JS perlu mengetahui cara kerja generator, hanya untuk memahami fitur struktur internal desain async / menunggu. Tetapi menggunakannya secara langsung dalam kode Anda sendiri tidak sepadan. Generator memperkenalkan dalam JavaScript kemampuan untuk menjeda fungsi dan kembali ke sana ketika (dan jika) pengembang menganggapnya perlu. Sejauh ini, saat bekerja dengan fungsi JS, kami berharap bahwa mereka, ketika dipanggil, hanya dieksekusi dari awal hingga akhir. Kemampuan untuk menjeda mereka sudah merupakan sesuatu yang baru, tetapi fungsi ini mudah diimplementasikan dalam async / menunggu konstruksi.

Tentu saja, orang bisa membantah pendapat ini. Sebagai contoh, salah satu argumen yang mendukung generator adalah bahwa mengetahui cara kerjanya berguna untuk men-debug kode dengan async / wait, karena generator disembunyikan di dalam konstruk ini. Namun, penulis bahan percaya bahwa ini, bagaimanapun, adalah sesuatu selain penggunaan generator dalam kode asli.

Pembaca yang budiman! Apa pendapat Anda tentang generator? Mungkin Anda tahu beberapa opsi untuk penggunaannya yang membenarkan aplikasi langsung mereka dalam kode proyek JS?

Kode promosi kerajaan untuk diskon 10% di server virtual kami:

Source: https://habr.com/ru/post/id417481/


All Articles