複数のファイルを次々にブラウザにストリーミングしたい。たとえば、複数の CSS ファイルを 1 つに連結して配信することを考えてみてください。
私が使用しているコードは次のとおりです。
var directory = path.join(__dirname, 'css');
fs.readdir(directory, function (err, files) {
async.eachSeries(files, function (file, callback) {
if (!endsWith(file, '.css')) { return callback(); } // (1)
var currentFile = path.join(directory, file);
fs.stat(currentFile, function (err, stats) {
if (stats.isDirectory()) { return callback(); } // (2)
var stream = fs.createReadStream(currentFile).on('end', function () {
callback(); // (3)
});
stream.pipe(res, { end: false }); // (4)
});
}, function () {
res.end(); // (5)
});
});
アイデアは、私が
- ファイル拡張子を持たないすべてのファイルを除外します
.css
。 - すべてのディレクトリを除外します。
- ファイルが完全に読み取られたら、次のファイルに進みます。
- 各ファイルを閉じずに応答ストリームにパイプします。
- すべてのファイルがパイプされたら、応答ストリームを終了します。
問題は、最初の.css
ファイルのみがパイプ処理され、残りのファイルがすべて失われることです。最初の (4) の後に (3) が (5) に直接ジャンプするかのようです。
興味深いのは、行 (4) を次のように置き換えると、
stream.on('data', function (data) {
console.log(data.toString('utf8'));
});
すべてが期待どおりに機能します。複数のファイルが表示されます。次に、このコードを次のように変更すると
stream.on('data', function (data) {
res.write(data.toString('utf8'));
});
最初のものを期待するすべてのファイルが再び欠落しています。
私は何を間違っていますか?
PS: Node.js 0.8.7 と 0.8.22 を使用するとエラーが発生します。
アップデート
さて、コードを次のように変更すると機能します。
var directory = path.join(__dirname, 'css');
fs.readdir(directory, function (err, files) {
var concatenated = '';
async.eachSeries(files, function (file, callback) {
if (!endsWith(file, '.css')) { return callback(); }
var currentFile = path.join(directory, file);
fs.stat(currentFile, function (err, stats) {
if (stats.isDirectory()) { return callback(); }
var stream = fs.createReadStream(currentFile).on('end', function () {
callback();
}).on('data', function (data) { concatenated += data.toString('utf8'); });
});
}, function () {
res.write(concatenated);
res.end();
});
});
しかし、なぜ?res.write
最初にすべてのチャンクを合計してから一度に書き込む代わりに、複数回呼び出すことができないのはなぜですか?