Generator adalah gaya JavaScript Coroutine (Coroutine). Ini mengacu pada fungsi yang dapat dijeda dan kemudian dilanjutkan selama eksekusi. Fungsi ini disertai dengan simbol asterisk dalam fungsi, seperti fungsi*, dan beberapa kata kunci karakteristik dalam fungsi, seperti hasil dan hasil*.
Fungsi* GeneratorFn () {Console.log ('Look Ma i ditangguhkan')} var generator = generatorfn () // [1] setTimeout (function () {generator.next () // [2]}, 2000)[1] dan [2] yang ditandai dalam kode dijelaskan sebagai berikut:
1. Ini adalah generator yang dimulai dengan jeda. Tidak ada output konsol saat ini.
2. Hanya dengan menelepon metode berikutnya () dapat dieksekusi dan dijalankan sampai menemukan kata kunci imbal hasil berikutnya atau kembali. Sekarang kami memiliki output konsol.
Mari kita lihat kasus lain:
fungsi *generator () {console.log ('start!'); var i = 0; while (true) {if (i <3) menghasilkan i ++; }} var gen = generator ();Kode di atas mirip dengan yang pertama, tetapi ada kata kunci hasil tambahan dalam fungsi generator. Ketika kode di atas dipanggil, itu tidak akan segera dieksekusi, tetapi akan menjeda keadaan siaga, sehingga tidak akan ada output awal. Itu tidak dieksekusi sampai panggilan berikutnya ().
var ret = gen.next (); // start! console.log (ret); // {value: 0, selesai: false}RET di atas adalah hasil generator. Ini memiliki dua properti:
■ Nilai, nilai hasil dalam fungsi generator,
■ Selesai, ini adalah bendera yang menunjukkan apakah fungsi generator kembali.
Lanjutkan kode sebagai berikut:
console.log (gen.next ()); // {value: 1, selesai: false} console.log (gen.next ()); // {value: 2, done: false} console.log (gen.next ()); // {value: tidak terdefinisi, dilakukan: true}Generator tidak memiliki misteri dalam pemrograman sinkron, dan sangat cocok untuk pemrograman asinkron.
Generator memiliki dua karakteristik:
1. Anda dapat memilih untuk melompat keluar dari suatu fungsi, biarkan kode eksternal memutuskan kapan harus melompat kembali ke fungsi ini dan melanjutkan eksekusi.
2. Mampu melakukan kontrol asinkron.
Lihatlah kode eksekusi asinkron berikut:
var gen = generator (); console.log (gen.next (). value); setTimeout (function () {console.log (gen.next (). value); console.log ('langkah pertama');}, 1000); console.log ('langkah kedua');Outputnya adalah:
0
Langkah 2
1
Langkah pertama
Dengan kata lain, Anda tidak akan menunggu batas waktu berakhir di SetTimeout, tetapi akan melanjutkan langsung dengan "langkah kedua" dan tidak akan diblokir di SetTimeout.
Mari kita lihat sepotong kode lain:
function* channel () {var name = yield 'halo, siapa nama Anda?' // [1] return 'well hai' + name} var gen = channel () console.log (gen.next (). Value) // halo, siapa nama Anda? [2] console.log (gen.next ('billy')) // well hai billy [3]Anda juga dapat menggunakan * selama traversal:
fungsi* iter () {for (var i = 0; i <10; i ++) Yield i} untuk (var val dari iter ()) {console.log (val) // output 1? -? 9}Kesalahpahaman umum
Karena saya dapat menjeda eksekusi fungsi, haruskah saya membiarkannya dieksekusi secara paralel? Tidak, karena JavaScript adalah satu utas, dan jika Anda ingin mencari peningkatan kinerja, generator bukan hidangan Anda.
Misalnya, kode berikut mengeksekusi angka fibonacci secara terpisah:
fungsi fib (n) {var current = 0, next = 1, swap for (var i = 0; i <n; i ++) {swap = arus, arus = selanjutnya next = swap+next} return arus} fungsi* fibgen (n) {var current = 0, next = 1, swap untuk (var i = 0; i <n; i ++) {swap = 1 swap = var i = 0; i <n; i ++) {swap = next = swap next for (var i = 0; i <n; i ++) {swap = swap = next noundHasil kinerja adalah sebagai berikut: (semakin tinggi semakin baik)
Hasil:
Reguler 1263899
Generator 37541
Generator bersinar
Generator dapat menyederhanakan kompleksitas fungsi dalam JavaScript.
Tugas malas
Meskipun penugasan malas dapat diimplementasikan menggunakan penutupan JS, menggunakan hasil akan sangat menyederhanakan. Melalui jeda dan pemulihan, kita bisa mendapatkan nilai numerik saat kita membutuhkannya. Misalnya, fungsi Fibgen di atas dapat menarik nilai -nilai baru saat kita membutuhkannya:
var fibiter = fibgen (20) var next = fibiter.next () console.log (next.value) setTimeout (function () {var next = fibiter.next () console.log (next.value)}, 2000) tentu saja, ini juga menggunakan loop: nol {next.Urutan tak terbatas
Karena Anda dapat malas untuk menetapkan nilai, Anda dapat melakukan beberapa trik Haskell, mirip dengan urutan yang tak terbatas. Di sini Anda dapat menghasilkan jumlah urutan yang tak terbatas.
Fungsi* fibgen () {var current = 0, next = 1, swap while (true) {swap = arus, arus = next next = swap + next hasil arus}}Mari kita lihat penugasan malas aliran Fibonacci dan minta mengembalikan nomor Fibonacci pertama setelah 5000:
untuk (var num fibgen ()) {if (num> 5000) break} console.log (num) // 6765Kontrol proses asinkron
Menggunakan generator untuk mengimplementasikan kontrol proses asinkron, paling umum berbagai paket perpustakaan janji, jadi bagaimana cara kerjanya?
Di dunia simpul, semuanya terkait dengan callbacks, yang merupakan fungsi asinkron tingkat rendah kami. Kita dapat menggunakan generator untuk membangun saluran komunikasi, untuk menulis kode asinkron dengan gaya pemrograman sinkron.
run (function* () {console.log ("start") var file = yield readfile ("./ async.js") // [1] console.log (file.toString ())}))Catatan 1 berarti bahwa program akan berlanjut sebelum menunggu async.js untuk mengembalikan hasilnya.
Genify adalah kerangka kerja yang membawa generator ke lingkungan pemrograman yang normal, menggunakan yang berikut:
NPM Instal Genify untuk instalasi, kode ini sebagai berikut:
var q = membutuhkan ('q'); var fs = membutuhkan ('fs'); var genify = membutuhkan ('genify'); // Bungkus objek Anda ke Genify functionVar objek = Genify ({concatfiles: function * (file1, file2, outfile) {file1 = hasil q.nfcall (fs.readfile, file1); file2 = yield q.nfcall (fs.readfile, file2); var concated = file2; file2; yield) qreadfile, file2); var var concated = file2; file2; yield) qreadfile, file2); var concated = file1 + file2; yielse (fs. Kembalinya kebetulan;}}); // Concatfiles adalah fungsi generator yang menggunakan kemampuan generator yang kuat. Object.concatFiles ('./ Somefile1.txt', './somefile2.txt', './concated.txt').then(function (res) {// lakukan sesuatu dengan hasil}, function (err) {// lakukan sesuatu dengan kesalahan});Penjelasan terperinci di atas tentang penggunaan generator JavaScript di Node.js adalah semua konten yang saya bagikan dengan Anda. Saya harap Anda dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.