【问题标题】:Nodejs send partial response not workingNodejs发送部分响应不起作用
【发布时间】:2015-10-01 10:18:42
【问题描述】:

我需要从 nodejs 发送部分响应,但此代码不起作用。 它会立即从数据库中获取 500 条记录,然后逐条处理每条记录。我想从 node.js 发送部分响应。如果我将数据存储在数组中,则会发生缓冲区溢出错误。

var exportData = function (req, res, next) {

    var limit = 500;
    var responseCount = 0;
    var loopCount = 1;
    var size = 30000;

    //Get 500 records at one time
    var getData = function (req, start, cb) {
        req.db.collection('items').find().skip(start).limit(limit).toArray(function (err, records) {
            if (err) throw err;
            cb(null, records);
        });
    };

    if (size > limit) {
        loopCount = parseInt(req.size / limit);

        if ((req.size % limit) != 0) {
            loopCount += 1;
        }
    }

    for (var j = 0; j < loopCount; j++) {

        getData(req, limit * j, function (err, records) {

            if (err) throw err;

            records.forEach(function (record) {
                //Process record one by one
            });

            res.write(records);

            if (++responseCount == loopCount) {
                res.setHeader('Content-type', 'application/csv');
                res.setHeader("Content-disposition", 'attachment; filename="import.csv"');
                res.end();

            }

        });
    }
};

【问题讨论】:

  • 也许你应该在调用res.write之前设置标题?
  • 我也试过这个东西,但没用
  • 您应该尝试流式传输响应。除非您需要以 X 组的形式将请求批量处理,否则您可以使用 through/through2 轻松地将 mongoose 中的每个项目通过处理逻辑管道传输到响应。
  • 您能否编辑代码以使用流式传输?
  • 我会试一试,但它仍然需要你自己修改,可能因为我没有在本地测试这个

标签: node.js


【解决方案1】:

来自 cmets: 您应该尝试流式传输。您的问题可能是因为您一次加载这么多记录的内存不足 - 您说您遇到溢出异常,所以可能是这种情况。这是使用 express/http.Server 进行流式传输的示例。我不能保证它有效,因为我从未使用 express/http.Server 进行流式传输,但它应该为您提供一个起点。

请注意,您通过管道发送到 result 的任何内容必须是字符串。

var through = require('through');

function exportData(request, result) {
  var limit = 500;

  res.setHeader('Content-type', 'application/csv');
  res.setHeader('Content-disposition', 'attachment: filename="import.csv"');

  req.db.collection('items')
    .find()
    .limit(limit)
    .stream()
    .pipe(through(function(record) {
      var processedRecord = processRecord(record);
      this.write(processedRecord);
    }))
    .pipe(result);
}


function processRecord(record) {
  // process record one by one
  return record;
}

【讨论】:

  • 我收到了这个错误 -> RangeError: Maximum call stack size exceeded
  • 那……令人印象深刻。你在什么硬件上测试这个?
  • Ubuntu 4GB 内存
  • 请使用修改后的代码 - 虽然我不完全确定会修复它。超出调用堆栈大小表示您一遍又一遍地调用同一个函数。
  • 你为什么问了两次这个问题? :S
猜你喜欢
  • 2015-09-29
  • 1970-01-01
  • 2013-12-07
  • 2019-07-12
  • 1970-01-01
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 2017-12-21
相关资源
最近更新 更多