Asyncjs/seriesByHand.js
fs.readdir('.', function(err, filenames) {
if (err) throw err;
function readFileAt(i) {
var filename = filenames[i];
fs.stat(filename, function(err, stats) {
if (err) throw err;
if (! stats.isFile()) return readFileAt(i 1);
fs.readFile(filename, 'utf8', function(err, text) {
if (err) throw err;
concatenation = text;
if (i 1 === filenames.length ){
ご覧のとおり、非同期バージョンには同期バージョンよりもはるかに多くのコードがあります。 filter や forEach などの同期メソッドを使用すると、コードの行数は約半分で済み、非常に読みやすくなります。これらの気の利いたイテレーターの非同期バージョンがあればどんなに素晴らしいでしょう。それを行うには Async.js を使用してください。
いつ捨てても大丈夫ですか?
Async.jsの関数記述方法
同期反復子で使用されるfilterとforEachメソッドを、対応する非同期メソッドに置き換えたいと考えています。 Async.js には 2 つのオプションがあります。async.filter と async.forEach は、指定された配列を並列処理します。
async.filterSeries と async.forEachSeries は、指定された配列を順番に処理します。
これらの非同期操作を並行して実行すると高速になるはずですが、なぜシーケンシャルなアプローチを使用するのでしょうか?理由は 2 つあります。前述した、ワークフローの順序が予測できないという問題。確かに、最初に結果を配列に格納してから、その配列を結合してこの問題を解決することもできますが、結局のところ、これはもう 1 つのステップです。
Node と他のアプリケーション プロセスが同時に読み取ることができるファイルの数には上限があります。この上限を超えると、オペレーティング システムはエラーを報告します。ファイルを順番に読み取ることができる場合は、この制限を心配する必要はありません。
それでは、まず async.forEachSeries について理解しましょう。以下ではAsync.jsのデータ収集メソッドを使用しており、同期版のコード実装を直接書き換えています。
Asyncjs/forEachSeries.js
コードをコピー
var async = require('async') ;
});
}
function readAndConcat(filename, callback) {
fs.readFile(filename, 'utf8', function(err, fileContents) {
concatenation = fileContents ;
コールバック();
});
}
function onComplete(err) {
console.log(concatenation);
}
これで、私たちのコードは 2 つの部分に見事に分割されました: タスクの概要 (async.filter 呼び出しと async.forEachSeries 呼び出しの形式) と実装の詳細 (2 つのイテレーター関数と完了コールバック onComplete の形式)。
標準の関数反復メソッドに対応する Async.js ユーティリティ関数は、filter と forEach だけではありません。 Async.js は次のメソッドも提供します:
reject/rejectSeries、フィルターの逆、
map/mapSeries、1:1 変換、
reduce/reduceRight、値の段階的な変換。フィルター;
sortBy、順序付けされたコピーを作成します。
some、少なくとも 1 つの値が指定された基準を満たすかどうかをテストします。
every、すべての値が指定された基準を満たすかどうかをテストします。
これらのメソッドは Async.js の本質であり、コードの重複を最小限に抑えながら一般的な反復作業を実行できるようにします。より高度なメソッドの検討を続ける前に、これらのメソッドのエラー処理手法を見てみましょう。
それを責めたいなら、これを最初に実行した Node の fs.exists を責めてください。これは、Async.js データ収集メソッド (filter/filterSeries、reject/rejectSeries、detect/detectSeries、some、every など) を使用するイテレーターがエラーを報告できないことも意味します。
Asyncjs/forEachSeries.js