2

コールバックの「終了」は、_flush に渡されたコールバックが完了した後にのみトリガーされることを期待していますが、_flush が完了する前にトリガーされています。なんで?

var stream = require('stream').Transform();

// Nothing interesting here
stream._transform = function (chunk, enc, next) {
  next();
};

// _flush makes an async call.
stream._flush = function (callback) {
  console.log("Expecting 1st: Entering _flush ");

  return process.nextTick(function () {
    console.log("Expecting 2nd: Done with _flush");
    callback();
  });
};

stream.on('finish',function () {
  console.log("Expecting 3rd: Entering finish callback-- should be flushed now.");
});

stream.end("chunk");

終了のnode.js ストリーム ドキュメントには、すべてのデータが基になるシステムにフラッシュされた場合にのみ、イベントがトリガーされると記載されています。

Node の Transform ストリーム実装のソース コードを見ると、_flushコールバックが呼び出されたときにのみ終了をトリガーすることが意図されているように見えます。

this.once('prefinish', function() {
  if (util.isFunction(this._flush))
    this._flush(function(er) {
      done(stream, er);
    });
else
   done(stream);
});

何か見逃しているか、これは Node の Transform ストリームのバグです。前者だと思いますが、私の問題を見つけていません。ご協力いただきありがとうございます!

更新:モジュールが提供するように、への呼び出しをprocess.nextTick()への同期呼び出しに置き換えると、問題がなくなることに注意してください。この問題は、 内の非同期呼び出しによってのみトリガーされます。sleepsleep_flush

4

3 に答える 3

3

ノード v0.10 では、_flush()'finish'で呼び出されるため、それが期待されていることをより明確に確認できます。

ただし、master (v0.11.x) では、新しい「prefinish」イベントが発明され、状況が少し変わったようです。ただし、コードを見ると、 prefinish() が呼び出され、 _flush() がトリガーされることがわかります。'prefinish' を発行した後に prefinish() が戻ると、'finish' が発行されます。これを行う前に、_flush() コールバックが呼び出されるのを待ちません。

したがって、結果の動作は両方のバージョンで同じです。動作を変更する必要があるかどうかは別の問題です。状況に関する github の問題を作成し、動作を変更することに関心があるかどうかを確認できます。

于 2014-05-13T01:31:25.670 に答える