這篇文章帶給大家的內容是關於ES6生成器用法介紹(附範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
概念
生成器是由生成器函數( generator function )運行後得到的,是可迭代的。
function* gen() { yield 'a'; yield 'b'; yield 'c'; } let g = gen(); // "Generator { }"
原理及簡單運用
生成器有一個很大的特點,它可以暫停內部程式碼運行,並傳回一個值給外部函數。 (暫停後不會阻止其他程式碼運作)當外部呼叫其 next 方法後,會繼續執行剩餘的程式碼,並接受外部傳來的一個參數。這個實作主要依賴關鍵字 yield 。
yield 關鍵字使生成器函數執行暫停,yield 關鍵字後面的表達式的值會傳回給生成器的呼叫者。它可以被認為是一個基於生成器的版本的 return 關鍵字。
function* g(){ var a = yield 2; console.log(a); } var it = g(); // 返回一个可迭代的生成器对象 console.log(it.next()); // 执行生成器函数内部代码,第一次返回 {done: false, value: 2} it.next(3); // 继续执行生成器函数内部代码,同时向生成器传递参数3,最后返回 {done: true, value: undefined}
一個簡單的計數器
function* count(){ var n = 1; while(true){ yield n++; } } var it = count(); it.next(); // 1 it.next(); // 2 it.next(); // 3
#用同步方式寫非同步程式碼
##以前處理非同步 ajax 請求結果,一般採用傳遞回呼函數的方式。一旦遇到多層回呼嵌套,程式碼的可讀性會降低,而且偵錯起來也不方便。有了生成器之後,我們就可以用同步的方式寫非同步的程式碼。這聽起來非常的有意思。我們的程式碼將會是這樣的function foo(){ var result = asyncFun(); // asyncFun 是异步函数,result 是异步返回的结果 console.log(result); }當然,上面的程式碼並不能得到正確的結果,它只是一個設想。我們正打算用生成器來實現,而且這是可行的。想想生成器有哪些特點:
function* foo(){ // 这里遇到了异步方法,必须停下来。 // 等待异步方法执行完毕,并返回结果,继续运行代码。当然,同步 ajax 不能算,它不是异步 // 输出结果 }靜下來想想有哪些關鍵字,與暫停、繼續有關。停下來...繼續...停下來...繼續...停下來...繼續...
Don't...Stop...Don't...Stop... Don't...Stop......這兩個字就是yield、next.
function *foo(){ var result = yield asyncFun(next); console.log(result); }當程式碼遇到
yield 會暫停,這個時候asyncFun 函數是不會暫停的,會執行,等執行完畢,再呼叫生成器的next 方法,並將返回結果作為參數傳給next。由於在生成器函數內部我們拿不到 next,必須藉助於全域變數來傳遞 next。
var next, gn; function asyncFun(next){ // 模拟异步请求 setTimeout(function(){ // 返回一个随机数 next(Math.random()) }, 1000) } function* foo(){ var result = yield asyncFun(next); console.log(result); } gn = foo(); next = gn.next.bind(gn); next(); // 打印随机数這樣寫,運行看起來有些繁重。可以寫一個包裝函數來運行含有非同步程式碼的生成器函數。
function asyncFun(next){ // 模拟异步请求 setTimeout(function(){ // 返回一个随机数 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生成器用法介紹(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!