您好,登錄后才能下訂單哦!
小編給大家分享一下ES6生成器怎么使用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
概念
生成器是由生成器函數(shù)( generator function )運行后得到的,是可迭代的。
function* gen() { yield 'a'; yield 'b'; yield 'c'; } let g = gen(); // "Generator { }"
原理及簡單運用
生成器有一個很大的特點,它可以暫停內(nèi)部代碼運行,返回一個值給外部函數(shù)。(暫停后不會阻止其他代碼運行)當外部調(diào)用其 next 方法后,會繼續(xù)執(zhí)行剩下的代碼,并接受外部傳來的一個參數(shù)。這個實現(xiàn)主要依賴于關(guān)鍵字 yield 。
yield 關(guān)鍵字使生成器函數(shù)執(zhí)行暫停,yield 關(guān)鍵字后面的表達式的值返回給生成器的調(diào)用者。它可以被認為是一個基于生成器的版本的 return 關(guān)鍵字。
function* g(){ var a = yield 2; console.log(a); } var it = g(); // 返回一個可迭代的生成器對象 console.log(it.next()); // 執(zhí)行生成器函數(shù)內(nèi)部代碼,第一次返回 {done: false, value: 2} it.next(3); // 繼續(xù)執(zhí)行生成器函數(shù)內(nèi)部代碼,同時向生成器傳遞參數(shù)3,最后返回 {done: true, value: undefined}
一個簡單的計數(shù)器
function* count(){ var n = 1; while(true){ yield n++; } } var it = count(); it.next(); // 1 it.next(); // 2 it.next(); // 3
用同步方式寫異步代碼
以前處理異步 ajax 請求結(jié)果,一般采用傳遞回調(diào)函數(shù)的方式。一旦遇到多層回調(diào)嵌套,代碼的可讀性會降低,并且調(diào)試起來也不方便。有了生成器之后,我們就可以用同步的方式寫異步的代碼。這聽上去非常的有意思。我們的代碼將會是這樣的
function foo(){ var result = asyncFun(); // asyncFun 是異步函數(shù),result 是異步返回的結(jié)果 console.log(result); }
當然,上面的代碼并不能得到正確的結(jié)果,它只是一個設(shè)想。我們正打算用生成器來實現(xiàn),而且這是可行的。想想生成器有哪些特點:
這就足夠了。有了生成器函數(shù),現(xiàn)在我們重新來設(shè)計代碼:
function* foo(){ // 這里遇到了異步方法,必須停下來。 // 等待異步方法執(zhí)行完畢,并返回結(jié)果,繼續(xù)運行代碼。當然,同步 ajax 不能算,它不是異步 // 輸出結(jié)果 }
靜下來想一想有哪些關(guān)鍵字,與暫停、繼續(xù)有關(guān)。停下來...繼續(xù)...停下來...繼續(xù)...停下來...繼續(xù)...Don't...Stop...Don't...Stop...Don't...Stop......這兩個詞就是 yield、next.
function *foo(){ var result = yield asyncFun(next); console.log(result); }
當代碼遇到 yield 會暫停,這個時候 asyncFun 函數(shù)是不會暫停的,會執(zhí)行,等執(zhí)行完畢,再調(diào)用生成器的 next 方法,并將返回結(jié)果作為參數(shù)傳給 next。由于在生成器函數(shù)內(nèi)部我們拿不到 next,必須借助于全局變量來傳遞 next。
var next, gn; function asyncFun(next){ // 模擬異步請求 setTimeout(function(){ // 返回一個隨機數(shù) next(Math.random()) }, 1000) } function* foo(){ var result = yield asyncFun(next); console.log(result); } gn = foo(); next = gn.next.bind(gn); next(); // 打印隨機數(shù)
這樣寫,運行看上去有些繁重。可以寫一個包裝函數(shù)運行含有異步代碼的生成器函數(shù)。
function asyncFun(next){ // 模擬異步請求 setTimeout(function(){ // 返回一個隨機數(shù) next(Math.random()) }, 1000) } function* foo(){ var result = yield function(next){asyncFun(next)}; console.log(result); } function wrapFun (gFn){ var gn = foo(), next = gn.next.bind(gn); next().value(next); } wrapFun(foo);
演示地址
不過,自從出了 Promise 和 await 之后,更多的是用這個組合,其使用也更簡單,范圍也更廣。
以上是ES6生成器怎么使用的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。