4

複数のファイルを次々にブラウザにストリーミングしたい。たとえば、複数の 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)
  });
});

アイデアは、私が

  1. ファイル拡張子を持たないすべてのファイルを除外します.css
  2. すべてのディレクトリを除外します。
  3. ファイルが完全に読み取られたら、次のファイルに進みます。
  4. 各ファイルを閉じずに応答ストリームにパイプします。
  5. すべてのファイルがパイプされたら、応答ストリームを終了します。

問題は、最初の.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最初にすべてのチャンクを合計してから一度に書き込む代わりに、複数回呼び出すことができないのはなぜですか?

4

3 に答える 3

2

コードは完全に問題ありませんでしたが、間違っていたのは単体テストでした...

それを修正し、今ではチャームのように機能します:-)

于 2013-03-09T21:42:26.397 に答える