


Penjelasan terperinci tentang contoh ekspresi hasil fungsi penjana dalam JavaScript
Artikel ini membawa anda pengetahuan yang berkaitan tentang JavaScript terutamanya memperkenalkan anda kepada contoh terperinci tentang fungsi JS Generator fungsi The Generator ialah penyelesaian pengaturcaraan tak segerak yang disediakan oleh ES6 bersama-sama, saya harap ia akan membantu semua orang.
[Cadangan berkaitan: Tutorial video JavaScript, bahagian hadapan web]
Apakah Penjana function
Dalam Javascript, sebaik sahaja fungsi mula dilaksanakan, ia akan berjalan ke penghujung atau tamat apabila ia menemui pengembalian Tiada kod lain boleh mengganggunya semasa pelaksanaan, dan tiada nilai boleh dihantar ke badan fungsi dari di luar
Kemunculan fungsi Penjana (generator) memungkinkan untuk memecahkan operasi lengkap fungsi itu, dan tingkah laku tatabahasanya berbeza sama sekali daripada fungsi tradisional
Fungsi Penjana ialah tak segerak penyelesaian pengaturcaraan yang disediakan oleh ES6 , ia juga merupakan fungsi biasa dalam bentuk, tetapi mempunyai beberapa ciri ketara:
- Terdapat tanda bintang "*" antara kata kunci fungsi dan nama fungsi (disyorkan untuk letakkannya di sebelah kata kunci fungsi)
- Gunakan ungkapan hasil dalam badan fungsi untuk mentakrifkan keadaan dalaman yang berbeza (mungkin terdapat berbilang hasil)
- Memanggil fungsi Penjana secara langsung tidak akan melaksanakannya, mahupun adakah ia akan mengembalikan hasil yang sedang dijalankan, tetapi akan mengembalikan Objek Iterator
- memanggil kaedah seterusnya objek Iterator dalam urutan, merentasi setiap keadaan di dalam fungsi Penjana
// 传统函数 function foo() { return 'hello world' } foo() // 'hello world',一旦调用立即执行 // Generator函数 function* generator() { yield 'status one' // yield 表达式是暂停执行的标记 return 'hello world' } let iterator = generator() // 调用 Generator函数,函数并没有执行,返回的是一个Iterator对象 iterator.next() // {value: "status one", done: false},value 表示返回值,done 表示遍历还没有结束 iterator.next() // {value: "hello world", done: true},value 表示返回值,done 表示遍历结束
Sebagaimana anda boleh lihat dalam kod di atas Operasi fungsi tradisional dan fungsi Penjana adalah berbeza sama sekali memanggil kaedah seterusnya objek Iterator Perlaksanaan kelihatan lebih seperti "ditendang sebelum bergerak"
function* gen() { yield 'hello' yield 'world' return 'ending' } let it = gen() it.next() // {value: "hello", done: false} it.next() // {value: "world", done: false} it.next() // {value: "ending", done: true} it.next() // {value: undefined, done: true}
Kod di atas mentakrifkan fungsi Penjana, yang mengandungi dua ungkapan hasil dan pernyataan pulangan (iaitu, jana Tiga keadaan)
Setiap kali kaedah seterusnya objek Iterator dipanggil, penunjuk dalaman akan memulakan pelaksanaan dari kepala fungsi atau di mana ia berhenti kali terakhir sehingga ia menemui ungkapan hasil seterusnya atau Pulangan kenyataan berhenti seketika. Dalam erti kata lain, fungsi Penjana dilaksanakan dalam bahagian, ungkapan hasil ialah tanda untuk menjeda pelaksanaan, dan kaedah seterusnya boleh menyambung semula pelaksanaan
Apabila kaedah seterusnya dipanggil untuk kali keempat, kerana fungsi itu mempunyai menyelesaikan traversal dan pelaksanaan, ia tidak akan lagi Terdapat keadaan lain, jadi {value: undefined, done: true} dikembalikan. Jika anda terus memanggil kaedah seterusnya, nilai ini akan dikembalikan
ungkapan hasil
ungkapan hasil hanya boleh digunakan dalam fungsi Penjana Jika digunakan di tempat lain, ralat akan dilaporkan
function (){ yield 1; })() // SyntaxError: Unexpected number // 在一个普通函数中使用yield表达式,结果产生一个句法错误
Jika ungkapan hasil digunakan dalam ungkapan lain, ia mesti diletakkan di dalam kurungan
function* demo() { console.log('Hello' + yield); // SyntaxError console.log('Hello' + yield 123); // SyntaxError console.log('Hello' + (yield)); // OK console.log('Hello' + (yield 123)); // OK }
Ungkapan hasil digunakan sebagai parameter atau diletakkan di sebelah kanan tugasan ungkapan, dan kurungan tidak diperlukan
function* demo() { foo(yield 'a', yield 'b'); // OK let input = yield; // OK }
Perbezaan antara ungkapan hasil dan pernyataan pulangan
Serupa: kedua-duanya boleh mengembalikan nilai ungkapan serta-merta selepas pernyataan
Perbezaan:
- Setiap kali ia menemui hasil, fungsi akan menjeda pelaksanaan dan terus melaksanakan ke belakang dari kedudukan itu pada kali seterusnya; dan pernyataan kembali tidak mempunyai fungsi menghafal kedudukan
- Fungsi hanya boleh melaksanakan penyataan pulangan sekali, dan boleh terdapat sebarang bilangan hasil
ungkapan hasil*
dalam fungsi Penjana Jika anda memanggil fungsi Penjana lain fungsi Penjana, ia tidak akan mempunyai kesan secara lalai
function* foo() { yield 'aaa' yield 'bbb' } function* bar() { foo() yield 'ccc' yield 'ddd' } let iterator = bar() for(let value of iterator) { console.log(value) } // ccc // ddd
Dalam contoh di atas, apabila menggunakan for...of untuk melintasi objek traverse yang dijana oleh bar fungsi, hanya dua nilai status . bar itu sendiri dikembalikan. Pada masa ini, jika anda ingin memanggil foo dalam bar dengan betul, anda perlu menggunakan ungkapan hasil*
ungkapan hasil* digunakan untuk melaksanakan fungsi Penjana lain di dalam fungsi Penjana
function* foo() { yield 'aaa' yield 'bbb' } function* bar() { yield* foo() // 在bar函数中 **执行** foo函数 yield 'ccc' yield 'ddd' } let iterator = bar() for(let value of iterator) { console.log(value) } // aaa // bbb // ccc // ddd
parameter kaedah next()
Ungkapan hasil itu sendiri tidak mempunyai nilai pulangan atau ia sentiasa mengembalikan tidak ditentukan. Kaedah seterusnya boleh mengambil parameter, yang akan dianggap sebagai nilai pulangan bagi ungkapan hasil sebelumnya
function* gen(x) { let y = 2 * (yield (x + 1)) // 注意:yield 表达式如果用在另一个表达式中,必须放在圆括号里面 let z = yield (y / 3) return x + y + z } let it = gen(5) /*** 正确的结果在这里 ***/ console.log(it.next()) // 首次调用next,函数只会执行到 “yield(5+1)” 暂停,并返回 {value: 6, done: false} console.log(it.next()) // 第二次调用next,没有传递参数,所以 y的值是undefined,那么 y/3 当然是一个NaN,所以应该返回 {value: NaN, done: false} console.log(it.next()) // 同样的道理,z也是undefined,6 + undefined + undefined = NaN,返回 {value: NaN, done: true}
Jika parameter diberikan kepada kaedah seterusnya, hasil pulangan akan berbeza sama sekali
{ function* gen(x) { let y = 2 * (yield (x + 1)) // 注意:yield 表达式如果用在另一个表达式中,必须放在圆括号里面 let z = yield (y / 3) return x + y + z } let it = gen(5) console.log(it.next()) // 正常的运算应该是先执行圆括号内的计算,再去乘以2,由于圆括号内被 yield 返回 5 + 1 的结果并暂停,所以返回{value: 6, done: false} console.log(it.next(9)) // 上次是在圆括号内部暂停的,所以第二次调用 next方法应该从圆括号里面开始,就变成了 let y = 2 * (9),y被赋值为18,所以第二次返回的应该是 18/3的结果 {value: 6, done: false} console.log(it.next(2)) // 参数2被赋值给了 z,最终 x + y + z = 5 + 18 + 2 = 25,返回 {value: 25, done: true} }
Hubungan dengan antara muka Iterator
ES6 menetapkan bahawa antara muka Iterator lalai digunakan dalam atribut Symbol.iterator bagi struktur data, dengan kata lain, selagi struktur data mempunyai Simbol atribut .iterator, ia boleh dianggap sebagai " Iterable" (iterable).
Harta Symbol.iterator itu sendiri ialah fungsi, iaitu fungsi penjanaan traverser lalai bagi struktur data semasa. Melaksanakan fungsi ini akan mengembalikan traverser.
Memandangkan melaksanakan fungsi Generator sebenarnya mengembalikan iterator, Generator boleh diberikan kepada sifat Symbol.iterator objek, supaya objek mempunyai antara muka Iterator.
{ let obj = {} function* gen() { yield 4 yield 5 yield 6 } obj[Symbol.iterator] = gen for(let value of obj) { console.log(value) } // 4 // 5 // 6 console.log([...obj]) // [4, 5, 6] }
传统对象没有原生部署 Iterator接口,不能使用 for...of 和 扩展运算符,现在通过给对象添加Symbol.iterator
属性和对应的遍历器生成函数,就可以使用了
for...of 循环
由于 Generator 函数运行时生成的是一个 Iterator 对象,因此,可以直接使用 for...of 循环遍历,且此时无需再调用 next() 方法
这里需要注意,一旦 next() 方法的返回对象的 done 属性为 true,for...of 循环就会终止,且不包含该返回对象
{ function* gen() { yield 1 yield 2 yield 3 yield 4 return 5 } for(let item of gen()) { console.log(item) } // 1 2 3 4 }
Generator.prototype.return()
Generator 函数返回的遍历器对象,还有一个 return 方法,可以返回给定的值(若没有提供参数,则返回值的value属性为 undefined),并且 终结 遍历 Generator 函数
{ function* gen() { yield 1 yield 2 yield 3 } let it = gen() it.next() // {value: 1, done: false} it.return('ending') // {value: "ending", done: true} it.next() // {value: undefined, done: true} }
Generator 函数应用举例
应用一:假定某公司的年会上有一个抽奖活动,总共6个人可以抽6次,每抽一次,抽奖机会就会递减
按照常规做法就需要声明一个全局的变量来保存剩余的可抽奖次数,而全局变量会造成全局污染,指不定什么时候就被重新赋值了,所以往往并不被大家推荐
{ let count = 6 // 声明一个全局变量 // 具体抽奖逻辑的方法 function draw() { // 执行一段抽奖逻辑 // ... // 执行完毕 console.log(`剩余${count}次`) } // 执行抽奖的方法 function startDrawing(){ if(count > 0) { count-- draw(count) } } let btn = document.createElement('button') btn.id = 'start' btn.textContent = '开始抽奖' document.body.appendChild(btn) document.getElementById('start').addEventListener('click', function(){ startDrawing() }, false) }[object Object]
事实上,抽奖通常是每个人自己来抽,每抽一次就调用一次抽奖方法,而不是点一次就一次性就全部运行完,是可暂停的,这个不就是 Generator 函数的意义所在吗?
// 具体抽奖逻辑的方法 function draw(count) { // 执行一段抽奖逻辑 // ... console.log(`剩余${count}次`) } // 执行抽奖的方法 function* remain(count) { while(count > 0) { count-- yield draw(count) } } let startDrawing = remain(6) let btn = document.createElement('button') btn.id = 'start' btn.textContent = '开始抽奖' document.body.appendChild(btn) document.getElementById('start').addEventListener('click', function(){ startDrawing.next() }, false)
应用二:由于HTTP是一种无状态协议,执行一次请求后服务器无法记住是从哪个客户端发起的请求,因此当需要实时把服务器数据更新到客户端时通常采用的方法是长轮询和Websocket。这里也可以用 Generator 函数来实现长轮询
{ // 请求的方法 function* ajax() { yield new Promise((resolve, reject) => { // 此处用一个定时器来模拟请求数据的耗时,并约定当返回的json中code为0表示有新数据更新 setTimeout(() => { resolve({code: 0}) }, 200) }) } // 长轮询的方法 function update() { let promise = ajax().next().value // 返回的对象的value属性是一个 Promise 实例对象 promise.then(res => { if(res.code != 0) { setTimeout(() => { console.log('2秒后继续查询.....') update() }, 2000) } else{ console.log(res) } }) } update() }
【相关推荐:JavaScript视频教程、web前端】
Atas ialah kandungan terperinci Penjelasan terperinci tentang contoh ekspresi hasil fungsi penjana dalam JavaScript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian Dalam era digital hari ini, semakin banyak perniagaan dan perkhidmatan perlu menyediakan fungsi tempahan dalam talian. Adalah penting untuk melaksanakan sistem tempahan dalam talian yang cekap dan masa nyata. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian dan memberikan contoh kod khusus. 1. Apakah itu WebSocket? WebSocket ialah kaedah dupleks penuh pada sambungan TCP tunggal.

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Penggunaan: Dalam JavaScript, kaedah insertBefore() digunakan untuk memasukkan nod baharu dalam pepohon DOM. Kaedah ini memerlukan dua parameter: nod baharu untuk dimasukkan dan nod rujukan (iaitu nod di mana nod baharu akan dimasukkan).

JavaScript ialah bahasa pengaturcaraan yang digunakan secara meluas dalam pembangunan web, manakala WebSocket ialah protokol rangkaian yang digunakan untuk komunikasi masa nyata. Menggabungkan fungsi berkuasa kedua-duanya, kami boleh mencipta sistem pemprosesan imej masa nyata yang cekap. Artikel ini akan memperkenalkan cara untuk melaksanakan sistem ini menggunakan JavaScript dan WebSocket, dan memberikan contoh kod khusus. Pertama, kita perlu menjelaskan keperluan dan matlamat sistem pemprosesan imej masa nyata. Katakan kita mempunyai peranti kamera yang boleh mengumpul data imej masa nyata
