繰り返しますが、コールバックの非同期。 配列内

var nodes = arrayThatLeaks( linklist ) .leakMap( xhrLoad ) .leakFilter( responseNotEmpty ) .leakMap( insertInDocument ); //      Promise.resolve( arrayThatLeaks( linklist ) .leakMap( xhrLoad ) .leakFilter( responseNotEmpty ) .leakMap( makeDomNode ) ) .then( insertNodesInDocument );
      
      





同様のエントリがコメントで一度満たされ、それが実験を促した-脳のための運動。 チェーンエントリの形式での配列の非同期操作。



参照、警告、言い訳
通過して破壊し 、落下した場合はダウンロードして脱穀します。



ここに別の自転車が提示されていることは確かであり、誰かがこのコードの出現の事実を無知と考えるでしょう。 しかし、前述のように、この実験は、次のエンコーダーによるjavascript非同期シングルスレッドの「サドル」化の試みです。 コードを見る人は誰でもその品質によって落胆し、関数と変数の名前は読者が意味をなそうとするのを混乱させる可能性があります。 しかし、このコードが誰かにとって有用であり、無駄にならないという希望があります。


当然、メソッドハンドラーは、発生していることの非同期性を考慮して記述する必要があります。 それは簡単な方法で行われます:



 function responseNotEmpty( r, v ) { if( /* - cv*/ ) r( true ); else r( false ); }
      
      





ハンドラーの最初の引数はサービスプロシージャです-結果の受信者、2番目の引数は配列要素です。 結果のノードの配列には、プロシージャのチェーンを通過するときに値が入力されます。 結果の配列内の要素の順序は、どの要素が先に処理されるかによって異なります。つまり、初期配列の値は、map()でさえもインデックスを失います。



PromisesおよびAsynchronous Expectationsの最新のアプローチに目を向けると考えられていましたが、説明できない理由で破棄されました。 結果は、関数の半分で潜在的なリークからなるコードです。 そして、その構造は、callback-hellの巨大な実施形態です-100行あたり5ステップ。



2つの方法が考えられます



最初は、内部状態制御と非同期ハンドラーのチェーン全体の実行を備えた大きなオブジェクトを作成したかったのです。 これは、多次元配列、結果とフラグ、マイクロ関数、フラグ、カウンター、フラグを含むマップ全体の形式で表されました。 これは、配列の長さが変わらない1つのmap()メソッドに適していました。 ただし、フィルタリング方法を使用すると、マップの一部が不要になります。 インタプリタが物理メモリの不必要なリンクを幻にしたとしても、これらのリンクに触れないようにコードでこれを試してください。 さらに、メソッドの並列ブランチの実装により、マップはいくつかの次元でほとんど制御不能に成長します。



 var a1 = arrayThatLeaks( [/**/] ); a1.leakMap(/**/).leakFilter(/**/).leakMap(/**/); //  1 a1.leakFilter(/**/).leakReduce(/**/); //  2
      
      





2番目の現在のオプションでは、配列メソッドの呼び出しごとに個別の制御データセットを作成します。 ここで、言及された困難は変数カウンターに崩壊します(ほぼ)。 そして、多くのメソッドのために、ローカル非同期の「魔法」全体であるtakeforward()交換手順がチェーンに導入されました。 1つのメソッドのクロージャ内のこのプロシージャは、次のメソッドのクロージャから内部プロシージャを取得します。 書き込みプロセス中に正確に何を送信するかが判明し、ハンドラーを開始する手順とカウンターを制御する同期手順で十分であることがわかりました。



詳細に



最初のことは、予想どおり、一般的な補助手順を異なるメソッドの詳細からchain()関数に分離することでした。 ここで、メソッドのハンドラーとレシーバーはラップアラウンドし、前のメソッドへのバインドは、通常は前のtakeforward()プロシージャであるgiveback()引数を介して行われます。 out of chain()は結果の配列で、リークメソッドによって拡張されています。 配列はexpa()関数で展開されます。ここで、各メソッドはchain()操作の結果です。 同時に、メソッドを作成するために、メソッドのシンクロナイザー、レシーバー、およびプリプロセッサーがchain()に転送され、chain()が向きを変えてchain()クロージャーからいくつかのリンクを取得します。



このようなスキームは、意味が単純なmap()およびfilter()メソッドに対して機能します。 ただし、()を減らすには、中間値の外部ストレージを作成する必要があります。これにより、チェーン上で匿名が生成されます()。 おそらく将来、メソッドが増えると、chain()はより複雑になり、ソートなどの密結合値を持つメソッドをより適切に記述するようになるでしょう。



メソッドのロジックを決定する手順:



メソッドシンクロナイザーは 、内部カウンター制御プロシージャから起動され、その前のサーキット()クロージャーのカウンター、前のメソッドを完了するためのフラグ、そのメソッドのハンドラーを開始するリンク、次のメソッドを開始するリンク、および結果配列へのリンクを受け取ります。 単純なメソッドの場合、メソッド実行の完了のみがここで計算されます。 複雑なものの場合、ハンドラーが開始される順序は、必要なすべての値を置き換えてさらに決定されるため、起動へのリンクがシンクロナイザーに送られます。 1つのメソッドが同期されるたびに、後続のすべてのメソッドが同期されます-これにより、メソッドのロジックを事前に解決できます。



結果のレシーバーは、引数によって外部ハンドラー(メソッド引数)に挿入され、そこから値を受け取ります。 ラッパー内の各レシーバーは特定のインデックスに関連付けられており、チェーン内でさらに値を送信して同期を開始できます。 ここでチェーンを開始する必要はありません。取得した値は、処理を続行するために常に必要なものではないからです。 また、繰り返しなしでのみ、任意のインデックスを挿入できます。



メソッドのプリプロセッサは畳み込みロジックを実装するためだけに発生しました。もちろん、他のいくつかのメソッドにも役立ちます。 プリプロセッサの本質は、処理チェーンから値を傍受することにあります。 reduce()の場合、これは重要です。ハンドラーには2つの値が必要であり、1つはチェーンから取得されるためです。 さらに、プリプロセッサは同期を開始できますが、手順に起動リンクを振りかけないように、松葉杖に似ています。



最後に



したがって、メソッドのチェーンは、制御された非同期実行を保証するために隠されたプロシージャによって拡張および圧縮されます(他の方法は?)、そして配列値は、他を待たずに通過する場所、待機する場所、消滅する場所で処理されます。 ここでの漏れは、クロージャの連鎖のために自然であり、曲線リンクは連鎖全体を維持します。 配列を空にする場合、エラーをスローする場合、または結果を保存する場合の動作の概念的な問題もあります。



UPD:約束と組み合わせることができるようになりました。 これを行うために、データレシーバーのラッパーと外部の.then()メソッドにチェックがありましたが、これは約束のふりをするだけです。



All Articles