JavaScriptのGeneratorは使用を理解します.


Generator理解
Generator関数はES 6が提供する非同期プログラミングソリューションであり、このように理解できる.
  • は文法的には、まず、Generator関数が状態マシンであり、複数の内部状態がカプセル化されていると理解できる.Generator関数を実行するとエルゴードオブジェクトに戻ります.つまり、Generator関数はステータスマシン以外のエルゴードオブジェクト生成関数です.返したエルゴードオブジェクトは、Generator関数内部の各状態を順次巡回することができます.
  • 形式では、Generator関数は普通の関数ですが、2つの特徴があります.一つは、functionキーワードと関数名の間に星番号があります.第二に、関数の内部はyield表現を使って、異なる内部状態を定義します.
  • function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    
    var hw = helloWorldGenerator();
    Generator関数の呼び出し方法は普通の関数と同じで、関数名の後に丸括弧を入れます.違いは、Generator関数を呼び出した後、この関数は実行されず、戻ってきたのも関数運転結果ではなく、内部状態を指すポインタオブジェクト、つまり前の章で紹介したエルゴードオブジェクトです.次のステップは、エルゴードオブジェクトのnextメソッドを呼び出す必要があります.ポインタを次の状態に移動させます.つまり、nextメソッドを呼び出すたびに、内部ポインタは、関数の先頭または前回停止した場所から、次のyield表現(またはreturn文)に出会うまで実行されます.言い換えれば、Generator関数はセグメントで実行され、yield表現は実行を一時停止するフラグであり、next方法は実行を再開することができる.
    hw.next()
    // { value: 'hello', done: false }
    
    hw.next()
    // { value: 'world', done: false }
    
    hw.next()
    // { value: 'ending', done: true }
    
    hw.next()
    // { value: undefined, done: true }
    上のプログラムは4回nextを実行しました.
  • の最初の呼び出しは、最初のyield表現に出会うまでGenerator関数が実行を開始する.nextメソッドはオブジェクトを返します.value属性は現在のyield表現の値hello、done属性の値falseです.
  • 第二の呼び出しは、Generator関数が最後のyield表現から停止したところから、次のyield表現まで実行されます.nextメソッドが返したオブジェクトのvalue属性は現在のyield表現の値worldであり、done属性の値falseは、巡回がまだ終わっていないことを表しています.
  • 第3の呼び出しは、Generator関数が前回のyield表現から停止したところから、return文まで実行されます(return文がない場合は関数終了まで実行されます).nextメソッドが返したオブジェクトのvalue属性は、return文の後に続く表式の値です.
  • の4回目の呼び出しは、Generator関数はすでに実行済みで、nextメソッドはオブジェクトのvalue属性がundefinedで、done属性はtrueです.後でnextメソッドを呼び出します.戻ってくるのはこの値です.
  • yield認識
    Generator関数が戻ってきたエルゴードオブジェクトは、nextメソッドを呼び出してこそ次の内部状態を巡回するため、実行を一時停止できる関数を提供しています.yield表現は休止フラグです.
    (1)yield表現に遭遇した場合は、後の動作を一時停止し、yieldの後に続くその表現の値を返す対象のvalue属性値とします.
    (2)次のnextメソッドを呼び出すと、次のyield表現に出会うまで継続して実行します.
    (3)新しいyield表現がない場合は、return文まで機能終了し、リターン文の後の表式の値を返し対象のvalue属性値として実行します.
    (4)この関数がreturn文がない場合やreturnを実行してからnextを実行する場合、戻る対象のvalue属性値はundefined、doneはtrueとなります.注意したいのですが、yield表現はGenerator関数にしか使えません.他のところで使うとエラーが発生します.yield表現は、別の表現の中で使用される場合、関数パラメータとして使用されるか、または与えられた表現の右側に置く必要があります.かっこは付けなくてもいいです.yieldを式に置くと、let s=(yield 1+2)、sの値はundefined、1+2の値は3の値はnextとして対象のvalueの値を返します.
    nextメソッド
    yield表現自体は戻り値がない、あるいは常にundefinedに戻ります.nextメソッドは前のyield表現の戻り値としてパラメータを持つことができます.
    このパラメータは上記の注意事項を解決した最後のもので、yieldの戻り値は常にundefinedであり、
    nextメソッドのパラメータは前のyield表現の戻り値を表していますので、nextメソッドを初めて使用した場合、伝達パラメータは無効です.V 8エンジンは直接にnextメソッドを使用した時のパラメータを無視します.nextメソッドを使用したのは2回目からです.パラメータは有効です.意味的には、最初のnext法はエルゴードオブジェクトを起動するために使用されますので、パラメータは必要ありません.
    yield*表現
    Generator関数の内部で別のGenerator関数を呼び出すと、デフォルトでは効果がありません.これはyield*式を使い、一つのGenerator関数の中でもう一つのGenerator関数を実行する必要があります.
    function* inner() {
      yield 'hello!';
    }
    
    function* outer1() {
      yield 'open';
      yield inner();
      yield 'close';
    }
    
    var gen = outer1()
    gen.next().value // "open"
    gen.next().value //          
    gen.next().value // "close"
    
    function* outer2() {
      yield 'open'
      yield* inner()
      yield 'close'
    }
    
    var gen = outer2()
    gen.next().value // "open"
    gen.next().value // "hello!"
    gen.next().value // "close"