我有一个来自mongo的流查询,并且正在将其传递给through2“间谍”可写流。它完全可以包含“ end”回调,其中包括5个文档的少量集合。但是,在有344个文档的较大集合中,只有前15个文档通过,然后它永远挂起,并且“ end”事件永远不会触发。这是MCVE:

var spy = require("through2-spy").obj;
var MongoClient = require("mongodb").MongoClient;

function getStream() {
  var stream = spy(function() {
    console.log("@bug counting", stream.total++);
  });
  stream.total = 0;
  return stream;
}

function onEnd() {
  console.log("ended");
}

MongoClient.connect(process.argv[2], function(error, db) {
  if (error) {
    console.error(error);
    return;
  }
  var stream = db.collection(process.argv[3]).find().stream();
  stream
    // behavior is the same with the follow line commented out or not
    .on("end", db.close.bind(db))
    .on("error", console.error)
    .on("end", onEnd)
    .pipe(getStream());
});

最佳答案

问题是through2-spy默认使用highWaterMark为16。为处理流控制,流维护了一个内部缓冲区,当从它们中消费数据时会清除该缓冲区。因为没有可读取的流消耗getStream返回的转换流中的数据,所以内部缓冲区将被填充并到达highWaterMark。增加highWaterMark应该可以解决此问题:

var stream = spy({highWaterMark: 350}, function() {
  console.log("@bug counting", stream.total++);
});


另一个非标准的替代方法是重置转换流的可读状态:

var stream = spy(function() {
    console.log("@bug counting", stream.total++);
    this._readableState.length = 0;
});

关于node.js - 未调用具有through2.spy结束的mongodb流查询,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29189888/

10-11 04:32