ホームページ  >  記事  >  ウェブフロントエンド  >  ES6 におけるジェネレーターとは何ですか? ES6 のジェネレーターの概要

ES6 におけるジェネレーターとは何ですか? ES6 のジェネレーターの概要

不言
不言転載
2018-10-17 16:42:584274ブラウズ

この記事の内容は、ES6 におけるジェネレーターとは何ですか? ES6 での Generator の導入は一定の参考になります。必要な方は参考にしていただければ幸いです。

ES6 のジェネレーター

ジェネレーターは ES6 の非常に興味深い機能ですが、理解するのが簡単ではない機能でもあります。 let/const がブロックレベルのスコープを提供するという明白な目的とは異なり、これの目的は何でしょうか?

まず、問題を明確にする必要があります。JavaScript では、関数の実行が開始されると、実行が完了するまで停止することはできません (デバッグについては言わないでください。製品を使用していて、コードをデバッグする必要があるユーザーを見たことがありますか?

ただし、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 自体は一時停止状態になります。

この時点で、次のことを知っておく必要があります。

  • ジェネレーターは関数ではなく、関数でも、関数でもありません。

    g() はすぐに実行を開始しますが、実行されるとすぐに一時停止し、
  • g1.next() が中断されるたびに Iterator オブジェクトを返します。一時停止状態にして、次の yield に遭遇するまで実行します。 または return
  • yield に遭遇すると、yield の後の式が実行され、実行後の値が返され、その後に入ります。一時停止状態に戻ります。この時点では false です。
  • リターンが発生すると、値が返され、実行が終了します。つまり、完了します。 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();
次に、ジェネレーターを使用した非同期プログラムを見てみましょう:

    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);
            }
        } );
    }
この関数は、非同期プログラムではネストされたコールバックを使用しません。ただし、同期方法を直接使用してそれを書き留めます。おそらく原理としては、非同期プログラムが 2 つあり、Xiao Ming と Xiao Hon がそれらを指すのに使用されるということです。 Xiaohong は、実行する前に Xiaoming の実行が完了するまで待つ必要があります。その後、Xiaohong を実行するときに (yield によって) プログラムの実行を一時停止し、Xiaohong が結果を返すまで待機してから、次の Xiaohong (next() を実行します)。 )。

上記のプログラムでは、ジェネレーターを自動的に実行できるようにするために使用される co 関数を追加しました。率直に言うと、最初の非同期関数が返されると、 next() メソッドが自動的に呼び出され、次のコードが実行されます。

Generator と Koa

Koa は、Node.js に基づく Web アプリケーション フレームワークです。 Koa で処理される非同期プログラムは、主にネットワーク リクエスト (HTTP)、ファイル読み取り、データ クエリです。ここには多くの非同期シナリオがあり、プログラムの階層化を追加して従来のコールバック方式を使用すると、コールバックが多すぎます。

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

})
この書き方はプログラムの保守に非常に悪影響を及ぼし、全く不便です。ジェネレーターを用意したら、上記と同じ方法でプログラムを書くことができます。 Koa のオリジナル バージョンでは、この方法を使用して中間処理プログラムを「yield」(ミドルウェア) に変換しました。クライアント要求をミドルウェアの形式で処理すると、アプリ アプリケーションの開発がより柔軟になり、フレームワーク自体に制限されなくなります。 最新の Koa2 では、Genetator は廃止され、代わりに async/await が使用されます。

しかし、どの方法を使用する場合でも、本質は Promise を使用することです。

以上がES6 におけるジェネレーターとは何ですか? ES6 のジェネレーターの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。