首頁 >web前端 >js教程 >Generator在ES6中是什麼意思? Generator在ES6中的介紹

Generator在ES6中是什麼意思? Generator在ES6中的介紹

不言
不言轉載
2018-10-17 16:42:584288瀏覽

本篇文章帶給大家的內容是關於ES6中Generator是什麼意思? ES6Generator的介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

ES6中Generator

Generator是ES6一個很有趣的特性,也是不容易理解的特性。不同於let/const提供了塊級作用域這樣明顯的目的,這玩意兒被搞出來到底是乾嘛的?

首先我們需要明確一個問題,在JavaScript中,任何一個函數只要開始執行,便無法停止下來直到執行完成(別跟我提debug,你看過哪個用戶在使用產品的還得開個debug調試你的程式碼)。

but,Generator提供這種能力。看下面程式碼:

function *g(){
    console.log('start');
    yield 1;
    console.log('middle');
    yield 2;
    console.log('end');
}
var g1 = g();
console.log(g1.next()); 
// start
// {value: 1, done: false}
console.log(g1.next());  
// middle
// {value: 2, done: false}
console.log(g1.next());  
// end
// {value: undefined, done: true}

根據輸出結果,我們看到,在函數g中,碰到yield關鍵字,運行的程式會停下來。只有呼叫 next()方法,才會繼續執行函數g中的程式碼。所以函數g本身有暫停狀態。

至此,我們需要知道:

  • Generator不是函數,不是函數,不是函數;

  • g()不會立即出發執行,而是一上來就暫停,並返回一個Iterator物件;

  • #每次g1.next()都會打破暫停狀態去執行,直到遇到下一個yield或return

  • 遇到yield時,會執行yeild後面的表達式,並傳回執行之後的值,然後再進入暫停狀態,此時done: false。

  • 遇到return時,會傳回值,執行結束,也就是done: true

  • 每次g.next()的回傳值永遠都是{value: ... , done: ...}的形式

#Generator與非同步

##既然Generator可以函數停下來,有些腦洞清奇的人,想到了可不可以用Generator處理非同步程式。

先看一個傳統範例:

    function asyn(fn) {
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                fn();
                resolve(true);
            }, 1000);
        });
    }

    function main() {
        console.log('start');
        asyn(function(d) {
            console.log('async one');
            asyn(function(d) {
                console.log('async two');
                console.log('end');
            });
        });
    }

    main();
再來看看使用了Generator的非同步程式:

    function asyn(fn) {
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                fn();
                resolve(true);
            }, 1000);
        });
    }

    co(function*() {
        console.log('start');
        yield asyn(function(d) {
            console.log('async one');
        });

        yield asyn(function(d) {
            console.log('async two');
        });
        console.log('end');
    });

    function co(fn) {

        return new Promise((resolve,reject)=>{
            let g = fn();

            onFullfilled();
            function onFullfilled() {
                let ret = null;
                ret = g.next();
                next(ret);
            }

            function next(ret) {
                if(ret.done) return resolve(ret.value);
                ret.value.then(onFullfilled);
            }
        } );
    }
函數在非同步程式沒有採用巢狀回呼,是直接用同步的方式寫了出來。道理大概就是,有兩個非同步程序,用小明和小紅指涉它們。小紅需要等小明執行完了才可以被執行,那麼我們在執行到小明時,暫停程序的運行(通過yield),等到小明有了返回結果時,再執行後面跟著的小紅(next())。

在上面的程式中,我們加入了一個co函數,這個函數的作用是讓Generator自動執行下去。直白來說,就是當第一個非同步函數返回後,自動呼叫next()方法運行後面的程式碼。

Generator與Koa

Koa是基於Node.js的網路應用框架。在Koa中,處理的非同步程式主要是網路請求(HTTP)、檔案讀取和資料查詢。這裡面的非同步場景較多,如果再加上程式分層,採用傳統的callback方式,那回呼多了去了。

app.on('get', function(){
    auth(function(){
        router(function(){
            find(function(){
                save(function(){
                    render(function(){
                        //......
                    })
                })
            })
        })
    })

})
這樣寫法對於程式維護及其不利,毫無便捷性可言。在有了generator後,我們便可以像上面那種方式來寫程式。 Koa最初的版本就是透過這種方式,讓中間處理程序都轉換成一個個"yield"(中介軟體)。透過中間件的形式去處理客戶端請求,讓開發App應用程式更加靈活,不受框架自身限制。

在最新的Koa2中,已經拋棄了Genetator,轉而使用async/await。

但是無論採用哪種方式,其本質都是利用了Promise。

#

以上是Generator在ES6中是什麼意思? Generator在ES6中的介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除