async と Q 全般
私は Node.js 開発を学んでおり、非同期の「コールバック地獄」を管理するための戦略に頭を悩ませようとしています。私が調査した 2 つの主な戦略は、Caolan McMahon のasyncモジュールと、Kris Kowal の promise ベースのQモジュールです。
他の多くの人と同じように、私はまだどちらを使うべきかを理解するのに苦労しています。しかし、一般的に言えば、Promise と Q ベースのコードの方がやや直感的であることがわかったので、その方向に進んでいます。
一般的なコレクションのマッピング/連結
ただし、コレクションを管理するための async モジュールの関数の使用にはまだ行き詰まっています。Java と Python のバックグラウンドを持っているため、コレクションを扱うときのほとんどの場合、ロジックは次のようになります。
- 結果を格納する新しい空のコレクションを初期化します。
- 古いコレクションで for-each ループを実行し、各要素にロジックを適用して、その結果を新しい空のコレクションにプッシュします。
- for-each ループが終了したら、新しいコレクションの使用に進みます。
クライアント側の JavaScript では、jQuery のmap() 関数を使用することに慣れてきました...そのステップ 2 のロジックを渡し、ステップ 3 の結果を戻り値として取得します。基本的な考え方は同じような気がします。
async と Q を使用したコレクションのマッピング/連結
Node-side async モジュールには同様のmap関数とconcat関数がありますが、元のスコープ レベルで連結された結果を返すことはありません。結果を使用するには、代わりにコールバック地獄に降りる必要があります。例:
var deferred = Q.defer();
...
var entries = [???]; // some array of objects with "id" attributes
async.concat(entries, function (entry, callback) {
callback(null, entry.id);
}, function (err, ids) {
// We now have the "ids" array, holding the "id" attributes of all items in the "entries" array.
...
// Optionaly, perhaps do some sorting or other post-processing on "ids".
...
deferred.resolve(ids);
});
...
return deferred.promise;
then()
私の他の関数は promise ベースになっているため、チェーン に簡単に含めることができるように、promise オブジェクトを返すこのコードを用意しています。
本当に両方必要ですか?
明確にするのに苦労している究極の質問は、上記のコード例でasyncとQ の両方が本当に必要かということです。一般的に、非同期モジュールの制御フローをQスタイルのプロミスチェーンに置き換える方法を学んでいます...しかし、プロミスベースのアプローチでコレクションのマッピングまたは連結を行う方法はまだ「クリック」されていません。または、なぜできないのか、またはなぜそれが良くないのかを知りたいです。
上記の例で使用しているように、async と Q が連携して動作することを意図している場合は、それで問題ありません。しかし、Q を単独できれいに使用できるのであれば、追加のライブラリ依存関係を必要としないことを好みます。
(とんでもなく明白な何かを見逃していたらすみません。非同期イベント駆動型モデルは非常に異なる世界であり、私の頭はまだ泳いでいます。 )