ES6は、新しいジェネレータ関数を導入するキーワードを得ることができ、流れ関数の実装ペンディング、非同期プログラミングのためのソリューションを提供し、実行フローを変更する可能性を提供します。基本的な使い方
ジェネレータ関数合成
発電機を区別するために2つの共通機能部分があります。
-
まず、バック機能では、関数名の前に*があります。
-
内部関数は、式を得ています。
*は機能使用ジェネレータ関数を表し、降伏関数は、内部状態を定義するために使用されます。
関数 *のFUNC(){ console.log( "1" ); 収量 '1' ; console.log( "2" ); 歩留まり「2」。 console.log( "3" ); リターン「3」。 }
実装のメカニズム
ジェネレータ関数呼び出しと、通常の関数を呼び出し、関数名の後の()は、しかし、ジェネレータ関数は、その訪問者のオブジェクトのIteratorを呼び出すために、すぐに実行正常な機能を好きですが、オブジェクトの内部状態へのポインタを返していないことができます次の方法は、ポインタが機能ヘッドから実行を開始、またはの最後のストップを配置します。
VAR F =新しいFUNC();
f.next(); // 1 // {値: "1"、行わ:偽} f.next(); // 2 // {値"2"、行わ:偽} f.next(); // 3 // {値: "3"、行わ:真} f.next(); // {値:未定義、行わ:真}
関数発生器ヘッドは、印刷最初のものから開始行わ収率に停止し、値属性オブジェクトの戻り値として表現「1」の後ろに降伏値、
メソッドの訪問者の目的関数の戻り
次の方法
通常の状況下では、次のパラメータの方法は戻り値の収量発現は不定であり、時間を通過しません。前のステップの収量の戻り値として次の入力パラメータを、このパラメータ場合。
関数 * sendParameter(){ console.log( "ストラト" ); VAR X =収率'2' 。 console.log( "1:" + X)。 VaRの Y =収率'3' ; console.log( "2:" +のY)。 console.log( "全" +(X + Y))。 }
次のパラメータを渡すことはありません。
だっ sendp1 = )(パラメータを送信します。 sendp1.next(); // ストラト // {値"2"、行わ:偽} sendp1.next()。 // 1:未定義 // {値: "3"、行わ:偽} sendp1.next()。 // 2:未定義 // 全のNaN // {値:未定義、行わ:真}
次のパラメータの受け渡し
だっ sendp2 = )(パラメータを送信します。 sendp2.next( 10 )。 // ストラト // {値"2"、行わ:偽} sendp2.next(20 )。 // 1:20 // {値: "3"、行わ:偽} sendp2.next(30 )。 // 2:30 // 全50 // {値:未定義、行わ:真}
次の使用に加えて、他にも使用することができる...イテレータは発電機能が産生を介してループするオブジェクト。
復帰方法
この方法は戻り値を返し、トラバースジェネレータ機能を終了します。
この方法は、リターンパラメータを提供する場合のパラメータを返し、引数は、undefinedを返していない場合。
関数 *のFOO(){ 収率 1 。 収量 2 。 利回り 3 ; } そこ F = FOO(); f.next(); // {値:. 1、DONE:falseに} F. 戻る( "FOO" ); // {値: "FOO"、DONE:真へ} f.next(); // {値:未定義、DONE:真へ} スロー方法 スロー方法は、発電機は、関数の本体、及び、内部キャプチャ機能の外にスローさらによいです。 VaRの G = 関数 * (){ 試み{ 産出; } キャッチ(E){ console.log( 'キャッチインナー' 、e)前記 } }。 ここで、 I = G()。 i.next(); してみてください{ 私。投げる( 'A' ); 私。投げる( 'B' ); } キャッチ(E){ console.log( 'キャッチ外' 、e)前記 } // キャッチインナーA // B外キャッチ
ビジタ・オブジェクトは、内部機能本体キャッチ機能が実行されているので、生成関数の内部に捕捉される第一、及び第二の2つのエラーをスローし、このエラーをキャッチしないので、エラーが発生機能体をスローします、in vitroでのキャッチ機能を捕獲しています。
発現量*
*収量収量の発現は、内部ジェネレータ関数の戻りトラバースオブジェクトが別の関数発生器を呼び出す表します。
関数 *の呼び出し先(){ console.log( 'コーリー:' + (収率))。 } 関数 * 発信者(){ 一方(真){ 利回り *の呼び出し先(); } } CONST callerObj = 発呼者(); callerObj.next(); // {値:未定義、行わ:偽} callerObj.next( "A" )。 // 呼び出し先: // {値:未定義、行わ:偽} callerObj.next( "B" )。 // 呼び出し先:B // {値:未定義、行わ:偽} // 等同于 関数 *の発信者(){ 一方(真){ 用(VARの呼び出し先の値){ 降伏値; } } }
利用シナリオ
Iteratorを実装
オブジェクトがイテレータインターフェイスを横断する必要がない方法は提供します。
関数 * objectEntries(OBJ){ CONST propKeysの =のReflect.ownKeys(OBJ)。 用(propKeysのCONST propKey){ [propKey、OBJ [propKey]を得ました。 } } CONSTジェーン = {最初'ジェーン'、最後: 'ドゥ' }。 用(CONST objectEntries(ジェーン)の[キー値]){ console.log( `$ {キー} $ {値}`)。 } // 最初:ジェーン // 最後:ドウ
Reflect.ownKeys()は関係なく、オブジェクトのすべてのプロパティを返すシンボルを含む、プロパティを列挙するかどうか。
JSONオブジェクトは?トラバーサルのすることはできませんIteratorインターフェイスを通じて利用できません。側イテレータインターフェースと共にジェネレータ関数、オブジェクトはJSONを横切ることができるように