Generatorジェネレータ

5538 ワード

さぎょう

  • generatorは同期をシミュレートするために使用することができます.内裏の本質は非同期です.つまり、非同期の考え方で非同期プログラムを書く必要がありますが、同期で表現することができます.
  • generatorは、同期をシミュレートするために生まれたものではなく、複数の論理ストリーム、すなわち、アナログ同時を処理するために使用される.

  • 単純な使用

    function* showWords() {
        yield 'one';
        yield 'two';
        return 'three';
    }
    
    var show = showWords();
    
    show.next() // {done: false, value: "one"}
    show.next() // {done: false, value: "two"}
    show.next() // {done: true, value: "three"}
    show.next() // {done: true, value: undefined}
    

    非同期処理、キュー生成、ajax多層ネストなどに適した処理
    function fn1(){
        setTimeout(function(){
            console.log('fn1')
            g.next();
        },1000)
    }
    function fn2(){
        setTimeout(function(){
            console.log('fn2')
            g.next();
        },1000)
    }
    function fn3(){
        setTimeout(function(){
            console.log('fn3')
            g.next();
        },1000)
    }
    function* gen(){
        yield  fn1();
        yield  fn2();
        yield  fn3();
        return;
    }
    var g=gen();
    g.next();
    
  • と一般関数の違いは、(1)、functionと関数名の間にアスタリスク(*)が存在し、推奨アスタリスク(*)がfunctionに隣接している.(2)、関数体内部にyield式があります.yieldは一時停止フラグです.(3)、Generator関数の呼び出しはすぐには実行されず、関数の実行結果も返されず、内部状態を指すポインタオブジェクトが返される.つまり、遍歴オブジェクトです.next()メソッドを呼び出すと、ポインタの指向が次の状態を指すように変更されます.

  • nextロジック

  • yield式に遭遇すると後の操作を一時停止し、式の後の値を戻りオブジェクトのvalueの値
  • とする.
  • nextメソッドが次回呼び出されると、次のyield式
  • に遭遇するまで下に進みます.
  • 新しいyield式に遭遇しなければ、returnに遭遇するまで関数が終了し、returnの後の値を戻りオブジェクトのvalue値
  • として実行する.
  • returnがなければ、最後のvalueはundefined
  • です.
  • return文の戻り値はforには含まれません...ofサイクル中.
  • yieldはreturnの後ろに置いても無効です.

  • next()呼び出しのパラメータ

  • パラメータ値には注入機能があり、前のyieldの戻り値
  • を変更することができる.
    function* showNumbers() {
        var one = yield 1;
        var two = yield 2 * one;
        yield 3 * two;
    }
    
    var show = showNumbers();
    
    show.next().value // 1
    show.next().value // NaN  -->2 * undefined
    show.next(2).value // 6
    
  • 以上のコード:nextが1回目に呼び出された後に戻り値oneは1であるが、2回目にnextが呼び出されたときoneはundefinedである.generatorは対応する変数値を自動的に保存しないため、手動で指定する必要がある.このときtwo値はNaNであり、3回目にnextが呼び出されたときにyield 3*twoに実行され、前回yield戻り値twoをパラメータで2に設定することで、結果3*2=6
  • となる

    ジェネレータネスト

  • yield*は、別のジェネレータ
  • に続く
  • は、複数の
  • をネストすることができる
    function* showWords() {
        yield 'one';
        yield* showNumbers();
        return 'three';
    }
    
    function* showNumbers() {
        yield 10 + 1;
        yield 12;
    }
    
    var show = showWords();
    show.next() // {done: false, value: "one"}
    show.next() // {done: false, value: 11}
    show.next() // {done: false, value: 12}
    show.next() // {done: true, value: "three"}
    

    for...of代替next();

  • return文の戻り値はforには含まれません...ofサイクル中.
  • function* showNumbers() {
        yield 1;
        yield 2;
        return 3;
    }
    
    var show = showNumbers();
    
    for (var n of show) {
        console.log(n) // 1 2
    }
    

    ジェネレータとpromise

  • promiseの非同期実装プロセスは、呼び出し関数がurlに伝達される可能性があり、ajax要求関数が直ちに決定されるため、トリガされる.非同期要求は呼び出しコールバック関数、すなわちresolveを呼び出し、返されたresolve呼び出しthenメソッドに基づいてデータを取得する.
  •  function request(url) {
            return new Promise(function(resolve, reject) {
                //ajax resolve 
                ajax(url, resolve);
            });
        }
        request('url').then(function(res) {
            console.log(res);
        })
    
  • yieldとpromise総合
  • function foo(x) {
            return request('url' + x);
        }
        // promise 
    function* fn() {
           var text = yield foo(1);
    }
    var it = fn();
    // promise
    var p = it.next().value;
    // promise 
    p.then(function(text) {
        // 
       it.next(text);
    }
    

    ジェネレータとコモンシップ


    Thunk関数
    *  " " , , 。  Thunk  。
    
  • 両要素
  • には、callbackの関数であるパラメータが1つしかありません.
  • callbackの最初のパラメータはerrorです.
  • 
    //  readFile( )
    fs.readFile(fileName, callback);
    
    // Thunk readFile( )
    var readFileThunk = Thunk(fileName);
    readFileThunk(callback);
    
    var Thunk = function (fileName){
      return function (callback){
        return fs.readFile(fileName, callback); 
      };
    };
    
  • 上のコードでは、fsモジュールのreadFileメソッドは、ファイル名とコールバック関数の2つのパラメータを持つマルチパラメータ関数です.変換器処理により,パラメータとしてコールバック関数のみを受け入れる単一パラメータ関数になった.この単一パラメータバージョンはThunk関数と呼ばれています.
  • Thunk関数の本当の威力は、Generator関数を自動的に実行できることにある.
  • function co(generator) {
        return function(fn) {
            var gen = generator();
            function next(err, result) {
                if(err){
                    return fn(err);
                }
                var step = gen.next(result);
                if (!step.done) {// , value (thunk ), next 
                    step.value(next);
                } else {
                    fn(' ', step.value);
                }
            }
            next();
        }
    }
    

    次の操作を行います.
    function readFile(filename) {//  ,yield thunk 
        return function(callback) {
            require('fs').readFile(filename, 'utf8', callback);
        };
    }
    co(function* () {
        var file1 = yield readFile('./file/a.txt');
        var file2 = yield readFile('./file/b.txt');
    
        console.log(file1);// 1 
        console.log(file2);// 2 
        return 'done';
    })(function(err, result) {
        console.log(err,result)
    });
    
  • は、coモジュールおよびthunkify原理参照を直接導入することができる.http://blog.csdn.net/fendouzhe123/article/details/50426156

  • MDNの比較的に良いウェブサイト


    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*