61

私は Koa を使用して Web アプリを構築することを検討していますが、「非同期を簡単にする」さまざまなサポート技術/アプローチの中から選択し、適用する方法、時期、理由についてはよくわかりません (以下に記載されています)。

全体として、この主題に関する Web 上のさまざまなガイダンスは、特に進化するベスト プラクティス、または少なくともより優れたもの、およびどのようなシナリオであるかに関して、いまだに曖昧なままです。ウェブ上には、すべてを文脈に当てはめているものはほとんど、あるいはまったくないように思われます。

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

そのため、明るいコミュニティが、以下にリストされているテクノロジーに関する次の質問に答えて明確にするのに役立ちます (太字で示されています)。

-- a) どのように、またどのような状況で (該当する場合)、それらは相互に補完、補足、代替、および/または重複する解決策となりますか?

-- b) 速度性能、エラー処理の容易さ、およびデバッグの容易さに関して、それらのトレードオフは何ですか?

-- c) いつ、どこで、なぜ「あれ」よりも「これ」のテクノロジー、テクノロジーの組み合わせ、および/またはアプローチを使用する方がよいのでしょうか?

-- d) もしあれば、どの技術またはアプローチが「薄暗い星」である可能性がありますか.

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

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

テクノロジー:

*コア*

私の理解:

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

* コ *

私の理解:

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

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

具体的な質問:

-- Koa での Co の使用方法と、非 Koa コンテキストでの使用方法の違い。言い換えれば、Koa は完全に Co の正面を向いているのでしょうか?

-- より優れたジェネレーター ライブラリがある場合、Co を Koa のジェネレーター ライブラリのようなものに置き換えることはできますか? いずれかがあります?

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

私の理解:

-- それらはある意味では、Promises/A+ 仕様を実装するための「ポリフィル」です (Node がその仕様をネイティブに実行するまで)。
-- Bluebird の promisfyAll ユーティリティなど、プロミスの使用を促進するための非仕様の便利なユーティリティがさらにいくつかあります。

具体的な質問:

-- 私の理解では、ECMAScript-6 仕様は Promises/A+ 仕様を大幅に反映している/反映する予定ですが、それでも Node 0.11v の調和は Promises をネイティブに実装していません。(これでいいの?)しかしそうなったらQやBluebirdなどの技術はなくなるのでしょうか?

-- 「Q」と Bluebird がジェネレーターをサポートしているという趣旨の記事を読んだことがあります。これは何を意味するのでしょうか?たとえば、それらが Co と同じ有用性をある程度提供したということは、部分的には意味するのでしょうか。

*サンクと約束*

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

具体的な質問:

-- Bluebird の promisfy のようなものを使用することと、Thunkify (github com/visionmedia/node-thunkify) を使用することの長所と短所は?

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

この投稿とその質問にさらにコンテキストを与えるために、次の Web ページに示されている Koa の手法について議論し、対比することができれば (特に長所と短所に基づいて) 興味深いかもしれません。

-- a) www.marcusoft . net/2014/03/koaintro.html (サンクまたはプロミスはどこにあるのか、または何かが表示されないのですか?)

-- b) 強いループ。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 で使用する(?) 場合、どのようにうまくいきますか?

皆さんありがとう!

4

1 に答える 1

55

私はこの 1 か月間、ほぼ広範囲にジェネレーターを扱ってきたので、これを試してみることができるかもしれません。意見は最小限にとどめようと思います。混乱の一部を明確にするのに役立つことを願っています。

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

traceur や regenerator などのツールを開発に使用して、それらを半同等の ES5 に変換できるツールがあることに注意してください。古いブラウザをターゲットにしています。

発電機

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

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

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

send(),: これは値を生成器に送信し、yield の最後の値として扱い、次の反復を続行します

next(),: これにより、ジェネレーターの次の反復が続行されます

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

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

一時停止と再開ができるため、フロー制御を非常に強力に管理できます。

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

頭のてっぺんから思いつくのは、サスペンドと gen-run です。私はそれらすべてを試しましたが、最も柔軟性があります。まだジェネレーターに慣れていない場合は、サスペンドを実行する方が少し簡単かもしれませんが、私はそれを権威をもって言うことはできません.

ノードとベスト プラクティスに関する限り、co は現在、それに対応するために作成されたサポート ツールの量に勝っていると思います。サスペンドを使用すると、次点になる可能性が最も高くなります。

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

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

約束

意見は最小限に留めると言いましたが、私にとって約束はおそらく最も理解が難しい概念であると述べたいと思います。これらはコードを維持するための強力なツールですが、内部の仕組みを把握するのは難しく、高度なフロー制御に使用すると、かなりの問題が発生する可能性があります。

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

promise ライブラリ自体がすぐになくなることはありません。彼らは、ES6 仕様に組み込まれなかった done() が含まれる promise に多くの便利な機能を追加します。同じライブラリをブラウザとノードで使用できるという事実は言うまでもありません。

サンクス

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

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

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

サンク vs. プロミス

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

ただし、通常はエラー処理が必要なものを構築するため、サンクの全体的なパフォーマンスの向上は、コードに応じてプロミスを支持して簡単に均等化または脇に置くことができます。

いつ使用するか

ジェネレーター - ブラウザーまたはノードのみの 0.11.3 の Firefox であるかどうかにかかわらず、アプリケーションが最先端で実行できると安全に言える場合

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

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

両方を一緒に使用することも、どちらが問題にならないかが明らかなように保持できる限り使用することもできます。

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

コア

koa については詳しく説明しません。これは express に似ていますが、ジェネレーターを利用するように書かれていると言えば十分です。これにより、簡単なエラー処理やミドルウェアのカスケードなど、いくつかの独自の利点が得られます。以前は、これらすべてのタスクを実行する方法がありましたが、洗練されておらず、パフォーマンスが最も優れていないこともありました。

特記事項: ジェネレーターは、まだ探求されていない可能性の扉を開きます。制御フローが最初の設計ではなかった場合に使用できるのと同じように、JavaScript で通常問題となる他の多くの問題を解決するために使用できると確信しています。それらを他にどのように使用できるかを見つけるのは、おそらく私よりも頭が良いでしょうが、少なくともそれらをいじって、彼らが何ができるかをよりよく理解することを始めたいと思います. ES.next には、ジェネレーター向けの機能がさらに追加されています。

于 2014-04-16T08:13:04.167 に答える