NodeJSでコルーチンを実装する

iojsの出力により、v8で既に安定している関数、特にコルーチンに変換できるネイティブプロミスとジェネレーターを研究することになりました。 Habréには、ジェネレーターを使用してコルーチンをもう1つ実装し、co / bluebirdで実際に何が起こるかを理解する方法に関する記事がありませんでした。 魔法を恐れずに使い始めるには、猫の下でコルーチンをお願いします。





コルーチン(コルーチン)は、複数の入力ポイントを持つ関数(プログラム)です。 特定のポイントでそれを停止し、別のことをしてから、このポイントに再び戻り、新しいデータで続行することができます(必ずしも新しいデータではなく、同じ状態で)。 ファイバーはnodejs(例: node-fibers )のコルーチン実装の1つですが、C ++プラグインやメタプログラミングを作成せずに、ネイティブJavascriptメソッドのみで実装することについて話しているところです。




特に、コルーチンは同様のコードを書く機会を与えてくれます。

function timeout(ms, msg){ return new Promise(function(resolve, reject){ setTimeout(function(msg){ console.log(msg); resolve(msg); }, ms, msg); }); } var makeJob = function *(){ yield timeout(1000, 1); yield timeout(1000, 2); var user = yield getUser(); return user.info; }; generatorWrapper(makeJob);
      
      







非常に簡潔かつ明確に判明しました。 タイムアウトの代わりに、たとえば、データベースにデータを送り、同じ関数に直接データを返すなど、約束することができる他の関数があります。/コールバックではなく、非常に便利です promiseチェーンで可能なよりも便利に、順次非同期関数の実行を許可およびキャンセルします。

問題の全体的なポイントは、このgeneratorWrapperがどのように見えるかです。 そして、これはこの点で私の推論です。

 function async(gen){ var instance = gen(); //  ,     return new Promise(function(resolve, reject){ //       function next(r){ if (r.done) { resolve(r.value);//     resolve'  . } if (typeof(r.value.then)=='function')//  duck typing, ..   Promise   { r.value.then(function(someRes){ next(instance.next());// next    . }, function(e){ reject(e); }); } else { console.log(r.value); next(instance.next()); } } next(instance.next());//       }); }
      
      





この実装は、すべてがどのように機能するかを理解するためのイデオロギーですが、イデオロギーはc​​oとbluebirdでほぼ同じです。

もちろん、 cobluebird.coroutineは本格的な実装であり、他のジェネレーターとの連携など、並列処理と高度な処理の可能性があります。



コードは、JSのジェネレーターは、フォームのコードをコルーチンとして記述できるようにするものの、実際にはこれを対象としていないことを示しています。 ジェネレーター、キャプテンフーとトートロジーの言い訳、まず第一に、ジェネレーターとそれに怠laな計算を行うのが最も便利です。この方法でそれを使用することは、意図した目的ではありませんが、テストではパフォーマンスの低下に気付きませんでした。

一方、 await / asyncなどの将来の標準を見ると、すべてが原則としてこれまでのところではないことが明らかになり、製品の安定性を恐れることなく、iojs + co / bluebirdを使用して現在のジェネレーターベースのコルーチンを安全に使用できます。 そして、コルチンのすべての正しい実装がネイティブな約束を返すことを考えると、このすべては将来の標準と完全に互換性があります。



要約すると、これをiojsに落ち着いて使用します。 promiseで書かれたコードでは、これはすべて変更なしで起きます。 機能に何かを追加したい場合は、同じcoを調べて独自の何かを追加できます。この処理に問題はありません。 非同期レースをしたい場合は、これを否定しないでください。しかし、ジェネレータではなく、Promiseの別の関数でそれを行うか、独自のデータ形式を考え出さなければなりません。そうでなければ、ジェネレータで自由に感じてください。 。



PS原材料は申し訳ありませんが、改善にご協力ください。



All Articles