21

非同期イベントを処理するためのこれらのモジュール間のトレードオフを誰かが比較できるかどうか疑問に思っています。具体的には、Fibers.promise の代わりに Async を使用する理由について知りたいと思っています。これは、少なくとも現在テスト コードでかなり広範囲に使用しています。特に、Fibers.promise に見られる主な利点の 1 つは、スタック チェーンのフロント分岐を維持できるため、 を使用できるようtry { } catch { } finallyになり、また、リクエストが処理された後にレスポンスが終了することを保証できることです。

Q_oper8 を使っている人はいますか? 私はこれを別のページで見つけましたが、それはすでに死んでいるのか、それともチェックアウトする必要があるのか​​ 疑問に思っていました.

4

4 に答える 4

37

Q_oper8のことは聞いたことがないのでコメントはできませんが、逆の方向から見ていきます。最初に非同期について、次にファイバー(およびそのヘルパーライブラリ)について聞いたが、実際には後者は好きではない。

繊維の欠点

他のJavascript開発者に不慣れ

Fiberファイバーは、渡されたJavascriptコードの解釈を引き継ぐコンパイル済みのネイティブメソッドを介してコルーチンの概念をJavascriptに導入yieldし、待機中のコルーチンに戻るための呼び出しをインターセプトします。

これはあなたにとって重要ではないかもしれませんが、チームで作業する必要がある場合は、メンバーにコンセプトを教える必要があります(または、メンバーがGoなどの他の言語のコンセプトを経験していることを願っています)。

Windowsサポートなし

したがって、Fiberまたはその上に記述されたライブラリを使用するには、最初にプラットフォーム用にネイティブにコンパイルする必要があります。私はWindowsを使用していませんが、FiberはWindowsでサポートされていないため、すぐに使用できるライブラリのユーティリティが制限されることに注意してください。つまり、Fiberで記述された汎用のNode.jsライブラリはまったく見つかりません(とにかく、非同期で回避するコストのかかるコンパイル手順が追加されるため、おそらくありません)。

ブラウザに互換性がありません

これは、Fiberを使用して記述したコードは、ブラウザーで実行できないことを意味します。これは、記述したすべてが「Javascript」であっても、ネイティブコードをブラウザーと混合できないためです(ブラウザーユーザーとしての私もそうしません)。 "(構文的にはJavascriptですが、意味的にはそうではありません)。

より難しいデバッグ

「コールバック地獄」は見た目が良くないかもしれませんが、継続渡しスタイルには、コルーチンよりも優れた点が1つあります。これは、コールスタックから問題が発生した場所を正確に把握しており、逆方向にトレースできます。コルーチンは、プログラムの複数のポイントで関数に入り、3種類の呼び出しを終了できます:return、、、ここthrowyield()、後者はリターンポイントでもあります。

コルーチンを使用すると、「同時に」実行される2つ以上の関数間で相互実行が可能になり、イベントループで同時に複数のコルーチンのセットが実行される場合があります。従来のコールバックでは、関数の実行中に関数の外部スコープが静的であることが保証されているため、必要な場合は、これらの外部変数を1回だけチェックする必要があります。コルーチンでは、これらのチェックを毎回実行する必要がありますyield()(元のコルーチンでの使用は、実際のJavascriptのコールバックチェーンに変換されるため)。

基本的に、コルーチンの概念は、実装するためのメソッドではなく、Javascriptイベントループに存在する必要があるため、操作が難しくなると思います。

非同期を「より良い」ものにする理由は何ですか?

悪い方が良い

実際、それは一種の「より悪い」という考えです。Javascript言語を拡張していぼを取り除こうとする(そして私の意見では新しいものを作成する)のではなく、Asyncはメイクアップのようにそれらを隠すための純粋なJavascriptソリューションです。

明示的な制御フロー

非同期関数は、イベントループの障壁を越える必要があるさまざまなタイプのロジックフローを記述します。ライブラリは、そのロジックを実装するために必要なコールバックコードの実装の詳細をカバーし、ほぼ線形の順序で実行する必要がある関数を提供するだけです。それらはイベントループ全体で実行されます。

非同期メソッドの引数の周りの最初のインデントレベルを削除する場合は、コルーチンに対して余分なインデントはなく、次のように少数の追加のfunction(callback) {宣言行のみがあります。

var async = require('async');
var someArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
async.forEach(someArray,
function(number, callback) {
    //Do something with the number
    callback();
}, function(err) {
    //Done doing stuff, or one of the calls to the previous function returned an error I need to deal with
});

この場合、コードが使用しているすべての変数は、コードによって変更されていない場合、コードが実行される前にしか変更できなかったことがわかっているため、デバッグが容易になり、「戻る」メカニズムは1つだけです。 :callback()。成功すると何も表示せずにコールバックするか、問題が発生したときにコールバックにエラーを渡します。

コードの再利用は難しくありません

上記の例では、コードの再利用が困難になっていますが、そうである必要はありません。名前付き関数はいつでもパラメーターとして渡すことができます。

var async = require('async');

// Javascript doesn't care about declaration order within a scope,
// so order the declarations in a way that's most readable to you

async.forEach(someArray, frazzleNumber, doneFrazzling);

var someArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

function frazzleNumber(number, callback) {
    // Do something to number
    callback();
}

function doneFrazzling(err) {
    // Do something or handle error
}

機能的であり、必須ではありません

非同期モジュールは、命令型のフロー制御の使用を推奨せず、フロー制御の関数の使用を推奨します(イベントループを通過する部分に必要です)。

機能スタイルの利点は、ループの本体または条件を簡単に再利用できることと、コードのフローによりよく一致する新しい制御フロー「動詞」を作成できることです(非同期ライブラリ)、async.auto関数呼び出し順序の依存関係グラフの解決を実装する制御フローメソッドのように。(一連の名前付き関数を指定し、実行に依存する他の関数をリストし、auto最初に「独立した」関数を実行し、次に従属関数の実行が終了したときに基づいて実行できる次の関数を実行します。)

言語によって指示された命令スタイルに合うようにコードを書くのではなく、問題のロジックが指示するようにコードを書き、それを実現するために「接着」制御フローを実装します。

要約すれば

ファイバーは、Javascript言語を拡張するという性質上、Node.js内で大規模なエコシステムを開発することはできません。特に、Asyncがルック部門で80%の道を歩み、Javascriptのコルーチンの他の欠点がない場合はなおさらです。

于 2012-04-23T20:03:46.817 に答える
1

ネストされたコールバックの代わりに、クライアントで jQuery の Deferred 機能を使用し、サーバーで nodejs の jQuery Deferred を使用しています。コードが大幅に削減され、非常に読みやすくなりました。

http://techishard.wordpress.com/2012/05/23/promises-promises-a-concise-pattern-for-getting-and-showing-my-json-array-with-jquery-and-underscore/

http://techishard.wordpress.com/2012/05/29/making-mongoose-keep-its-promises-on-the-server/

于 2012-05-29T17:18:46.420 に答える