首頁  >  文章  >  web前端  >  ES6生成器用法介紹(附範例)

ES6生成器用法介紹(附範例)

不言
不言轉載
2019-03-18 11:19:212380瀏覽

這篇文章帶給大家的內容是關於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);
}
當然,上面的程式碼並不能得到正確的結果,它只是一個設想。我們正打算用生成器來實現,而且這是可行的。想想生成器有哪些特點:

    它能暫停,向外部傳回值
  1. 能繼續執行剩下的程式碼,並接受外部傳來的參數
這就夠了。有了生成器函數,現在我們重新來設計程式碼:

function* foo(){
    // 这里遇到了异步方法,必须停下来。
    // 等待异步方法执行完毕,并返回结果,继续运行代码。当然,同步 ajax 不能算,它不是异步
    // 输出结果
}
靜下來想想有哪些關鍵字,與暫停、繼續有關。停下來...繼續...停下來...繼續...停下來...繼續...

Don't...Stop...Don't...Stop... Don't...Stop......這兩個字就是yieldnext.

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);

示範地址

不過,自從出了

Promiseawait 之後,更多的是用這個組合,其使用也更簡單,範圍也更廣。

#

以上是ES6生成器用法介紹(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除
上一篇:Angular是什麼下一篇:Angular是什麼