web-dev-qa-db-ja.com

Koa / Co / Bluebird or Q / Generators / Promises / Thunks interplay? (Node.js)

私はKoaで一部Webアプリの構築を調査していますが、サポートする「非同期化を容易にする」技術/アプローチの範囲を選択する-と適用する-の方法、時期、理由についてはあまり把握していません(以下通り)。

全体的に、このテーマに関するWeb上のさまざまなガイダンスは、特に進化しているベストプラクティス、または少なくともより優れたもの、およびどのシナリオの下で、物事をぼやけたままにしています。コンテキスト上にすべてを配置するWeb上には、ほとんどまたはまったくないようです。

この大きなお尻の広大な投稿への応答がそれを修正できることを願っています。また、以下の質問は、誰かがこの問題に対処するために徹底的なブログ投稿などを書くように促すことができます。私の感覚では、その恩恵を受けるのは私だけではありません。

そのため、明るいコミュニティが、以下にリストされているテクノロジー(太字)に関して以下の質問に答え、明確にするのを手伝ってくれることを嬉しく思います。

-a)どのように、どのような状況下で(該当する場合)、相互に補完、補足、代替、および/または重複するソリューションがありますか?

-b)速度パフォーマンス、エラー処理の容易さ、デバッグの容易さに関するトレードオフは何ですか?

-c)いつ、どこで、なぜ「this」対「that」テクノロジー、テクノロジーコンボ、および/またはアプローチを使用する方が良いでしょうか?

-d)どのテクノロジーまたはアプローチが存在する場合、それが「薄暗い星」になる可能性があります。

(回答の一部である意見が十分に説明できることを願っています。)

==============================

テクノロジー:

* Koa *

私の理解:

Koaは、ビルドのための最小限の基盤です。Node ECMAScript-6の機能、特にジェネレーターの1つの機能を利用するためのアプリです。

* Co *

私の理解:

-Coは、ECMAScript-6ジェネレーター(Node .011ハーモニーのネイティブ)を実行するためのユーティリティのライブラリであり、作成の必要性をある程度/多く(?)軽減することを目標としています。ジェネレーターを実行および管理するための定型コード。

-Coは本質的にKoa(?)の一部です。

特定の質問:

-Koaの場合とKoa以外の場合でCoを異なる方法で使用する場合。言い換えれば、コアはCoを完全にファサード化していますか?

-Koaでは、より良いライブラリがあれば/あれば、ジェネレータライブラリのような他のライブラリに置き換えることができますか?いずれかがあります?

*「Q」やBluebirdなどのPromiseライブラリ*

私の理解:

-Nodeがその仕様をネイティブで実行する場合、Promises/A +仕様を実装するためのある意味で「ポリフィル」です。
-BluebirdのpromisfyAllユーティリティなど、使用の約束を容易にするための非仕様の便利なユーティリティがいくつかあります。

特定の質問:

-私の理解では、ECMAScript-6仕様はPromises/A +仕様を大部分反映する/するが、それでもNode 0.11vハーモニーはPromiseをネイティブに実装しません。(これは正しいですか?)しかし、そうなった場合、QやBluebirdなどのテクノロジーは登場するのでしょうか?

-「Q」とBluebirdがジェネレーターをサポートしているという事実を読んだことがあります。これは何を意味するのでしょうか?例えば、ある程度、Coと同じ効用を提供したということですか、もしそうならどの程度ですか?

*サンクと約束*

私は彼らが何であるかについて公正なハンドルを持っていると思いますが、誰かがそれぞれが何であるかについて簡潔で明確な「エレベーターピッチ」の定義を提供できることを望みます。コアではなく、コアコンテキストで。

特定の質問:

-Thunkify(github com/visionmedia/node-thunkify)を使用するのではなく、Bluebirdの有望なものを使用することの長所と短所は?

==============================

この投稿とその質問にもう少しコンテキストを与えるために、次のWebページで紹介されているKoaテクニックを議論し、対比することができれば興味深いかもしれません(特に長所対短所):

-a)www.marcusoft net/2014/03/koaintro.html(サンクや約束はどこですか、それとも私は何かを見ていませんか?)

-b)strongloop com/strongblog/node-js-express-introduction-koa-js-zone(再び、サンクや約束はどこにありますか?)

-c)github。 com/koajs/koa/blob/master/docs/guide.md(「次の」引数は何に相当し、何をどこに設定しますか?)

-d)blog.peterdecroos com/blog/2014/01/22/javascript-generators-first-impressions(Koaコンテキストではありませんが、Promiseライブラリ(Bluebird)でのCoの使用を提示するため、ここで提示するテクニック/パターンが役立つと想定していますそれ自体をKoaで使用できますか?

皆さんありがとう!

60
JLS

私は今月、ほぼ広範囲に発電機を使って仕事をしているので、これを突き止めることができるかもしれません。私は意見を最小限に抑えるようにします。混乱の一部を明らかにするのに役立つことを願っています。

ベストプラクティスとより良い説明がない理由の一部は、この機能がjavascriptでまだ非常に新しいことです。ジェネレーターnode.jsとfirefoxを使用できる場所はまだほとんどありませんが、firefoxは標準から少し外れています。

トレーサーやリジェネレータなどのツールを使用して開発に使用し、それらを準同等のES5に変えることができるので、それらを使って作業するのが楽しい場合は、それらを使用しない理由はありません。古風なブラウザをターゲットにしている。

発電機

ジェネレーターは、もともと非同期制御フローを処理する方法とは考えられていませんでしたが、すばらしい動作をします。ジェネレーターは基本的に、yieldを使用して実行を一時停止および再開できる反復関数です。

Yieldキーワードは基本的に、この反復でこの値を返すと言っており、再びnext()を呼び出したときに中断したところから始めます。

ジェネレーター関数は、最初に呼び出されたときに実行されず、代わりにいくつかのメソッドとfor-ofループおよび配列内包で使用される機能を持つ反復子オブジェクトを返すという点で特別な関数です。

send(),:これはジェネレーターに値を送り、それをyieldの最後の値として扱い、次の反復を続けます

next(),:ジェネレーターの次の反復を継続します

throw():これは、ジェネレーターに例外をスローします。これにより、ジェネレーターは、最後のyieldステートメントから来たかのように例外をスローします。

close():ジェネレーターに強制的に実行を返させ、ジェネレーターの最終コードを呼び出します。これにより、必要に応じて最終エラー処理をトリガーできます。

一時停止および再開する機能は、フロー制御の管理を非常に強力にするものです。

Co

Coは、フロー制御の処理を容易にするジェネレーターの機能を中心に構築されました。ジェネレーターでできることのすべてをサポートしているわけではありませんが、ほとんどのボイラープレートと頭痛で使用することでそれらのほとんどを使用できます。そして、フロー制御の目的のために、私はcoがすでに提供しているもの以外のものが必要だとは知りませんでした。公平を期すために、フロー制御中にジェネレーターに値を送信しようとしませんでしたが、興味深い可能性がいくつかあります。

私の頭の中で思いがけないいくつかのジェネレーター・ライブラリーがあります。それらはサスペンドであり、gen-runです。私はそれらをすべて試しましたが、共同は最も柔軟性を提供します。発電機にまだ慣れていない場合は、サスペンドの方がやや簡単かもしれませんが、権限があるとは言えません。

ノードとベストプラクティスに関する限り、現在、共同開発のために作成されたサポートツールの量を手にしています。サスペンドで最も可能性の高い次点者。

Coはプロミスとサンクの両方で機能し、yieldステートメントに使用されるため、next()を手動で呼び出す代わりにcoがジェネレーターの実行をいつ継続するかを知ることができます。 Coは、フロー制御をさらにサポートするために、ジェネレーター、ジェネレーター関数、オブジェクト、および配列の使用もサポートしています。

配列またはオブジェクトを生成することにより、生成されたすべてのアイテムに対して並列操作を実行できます。ジェネレーターまたはジェネレーター関数に譲ることにより、coは新しいジェネレーターが完了するまでさらに呼び出しを委任し、現在のジェネレーターで次の呼び出しを再開します。これにより、最小限の定型コードで非常に興味深いフロー制御メカニズムを効果的に作成できます。

約束

私は意見を最小限に抑えたいと言いましたが、約束はおそらく最も把握しにくい概念であると述べたいと思います。これらはコードを維持するための強力なツールですが、内部の仕組みを把握するのが難しく、高度なフロー制御に使用する場合はかなりの落とし穴があります。

約束を説明するために考えられる最も簡単な方法は、それらが関数の状態を維持する関数によって返されるオブジェクトであり、オブジェクトの特定の状態が入力されたとき、または呼び出されたときに呼び出すコールバックのリストです。

Promiseライブラリ自体は、すぐにはどこにも行きません。彼らは、ES6仕様に入らなかったdone()を含む約束のために、たくさんのNiceを追加します。ブラウザで同じライブラリを使用できるということは言うまでもなく、ノードでは長い間使用できます。

サンク

サンクは、単一のパラメーターコールバックを取得し、ラップしている別の関数を返す単なる関数です。

これにより、メソッドが完了したときに通知できるように、コールバックで渡す関数を呼び出し元のコードでインスタンス化できるようにするクロージャーが作成されます。

サンクは、私の意見では理解して使用するのはかなり簡単ですが、すべてに適したツールではありません。たとえば、スポーンはサンクを作成するための大きな痛みです。あなたはそれを行うことができますが、それは簡単ではありません。

サンクとプロミス

これらは相互に排他的ではなく、簡単に一緒に使用できますが、通常は正気度で1つを選択し、それを使用する方が適切です。または、少なくともコンベンションを選択して、どちらがどれであるかを簡単に判断できるようにします。サンクは私の経験からより高速に動作しますが、ベンチマークは行っていません。これはおそらく、抽象化が小さく、エラー処理メカニズムが組み込まれていないためです。

通常は、エラー処理を必要とするものを構築します。そのため、サンクの全体的なパフォーマンスの向上は、コードに応じて約束を優先するか、容易に均等になる可能性があります。

使用する場合

ジェネレーター-ブラウザーまたはFirefox専用のノードのみであるかどうかにかかわらず、アプリケーションが出血しているEdgeで実行できると安全に言うことができる場合> 0.11.3

私は今出ている会社でそれらを広範囲に使用してきましたが、制御フローのメカニズムとそれらが可能にする怠laな評価に満足できませんでした。

Promises vs. Thunks-これは本当にあなた次第です。それらは同じ利点を提供せず、同じ問題を解決しません。約束は非同期の問題に直接対処するのに役立ちます。サンクは、関数が他のコードを渡すために必要なコールバックパラメーターを取ることを保証するだけです。

それらを一緒に使用することも、問題が発生しないのが明らかであるように、それを保持できる限り、両方を使用することもできます。

ジェネレーターによる約束/サンク-制御フローにジェネレーターを使用しているときはいつでもこれを行うことをお勧めします。必須ではありませんが、ジェネレーターを使用した制御フローの抽象化としてcoを使用するのが簡単であるように簡単です。入力するコードが減り、メンテナンスが容易になり、他の誰かがまだ実行していないEdgeケースに遭遇する可能性が低くなります。

コア

コアについてはあまり詳しく説明しません。それは表現に似ていますが、ジェネレータを利用するように書かれていると言えば十分です。これにより、エラー処理が容易になり、ミドルウェアがカスケード接続されるなど、いくつかのユニークな利点が得られます。以前はこれらのタスクをすべて実行する方法がありましたが、それらはエレガントではなく、時には最もパフォーマンスがよくありませんでした。

特記事項:ジェネレーターは、まだまだ調査していない可能性の扉を開きます。それが初期設計ではなかったときに制御フローに使用できるのと同じように、私たちは通常JavaScriptで問題がある他の多くの問題を解決するために使用できると確信しています。他の方法を使用する方法を見つけるのはおそらく私よりも明るいでしょうが、少なくとも彼らと遊んで、彼らが何ができるのかをよりよく理解し始めるでしょう。 ES.nextに登場するジェネレーターには、さらに多くの利点があります。

54
Thot