【问题标题】:'Write after end' error with Express, csvtojson and node-walkExpress、csvtojson 和 node-walk 出现“结束后写入”错误
【发布时间】:2014-10-15 09:25:50
【问题描述】:

我在使用 Express 从 csv 文件发送 JSON 数据时遇到问题。它需要一个 CSV 文件的文件夹,循环遍历,将其全部转换为 JSON,然后在最后将其吐出,但在第一次加载后我收到错误 Error: write after end 和 (node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.。该错误仅适用于我尝试点击/get 路径,而不是主索引页面。

我知道这与关闭或未关闭的读取流有关,但我没有足够的知识来确切地确定要做什么。这是我的代码;任何建议都会很可爱。哒!

Ps,使用的技术有Express、Node-walk和CSVtoJSON。

init.js

var _ = require('underscore')._;
var express = require('express');

var server = express();

server.use(express.static(__dirname + '/frontend/public/'));
server.listen(1234);

var getData = require('./src/getData.js');

server.get('/get', function (req, res) {
  getData.get(function (data) {
    res.send(data);
  })
});

server.get('/', function (req, res) {
  res.sendFile('./index.html');
});

getData.js

var walk      = require('walk');
var fs        = require('fs');
var _         = require('underscore')._;
var csvtojson = require('csvtojson').core.Converter;

var files = [];

var csvConverter = new csvtojson({constructResult: true});

exports.get = function (callback) {

  var csvWalker = walk.walk('./place-csvs-here', {followLinks: false});

  csvWalker.on('file', function (root, stat, next) {
    if (stat.name.match(/[A-Z]+?\-\d+?\.csv/gi)) {
      var filename = root + '/' + stat.name;
      files.push(fs.createReadStream(filename));
    }
    next();
  });

  csvWalker.on('end', function () {
    files.forEach(function (file) {
      file.pipe(csvConverter);
    });
  });

  csvConverter.on('end_parsed', function (data) {
    if (callback) {
      // Ensure rows are unique.
      data = _.uniq(data, function (x) {
        return JSON.stringify(x);
      });
      // Required fields.
      data = _.filter(data, function (x) {
        return (
           x['Date']    !== undefined
        && x['Balance'] !== undefined
        && x['Date']    !== 'Date'
        && x['Balance'] !== 'Balance'
          );
      });
      callback(data);
    }
  });

}

【问题讨论】:

  • 有关内存泄漏警告,请参见此处stackoverflow.com/questions/15581978/…。它说它是核心中的一个错误并更改版本。
  • 你是在打/get 路由 11 次,然后在第 11 次收到 EventEmitter 消息吗?

标签: javascript node.js express


【解决方案1】:

您正在尝试为 所有 请求重复使用 files 和相同的 csv 转换器实例。您还尝试将许多文件同时通过管道传输到一个解析器实例。这可能会使解析器感到困惑。

试试这个getData.js:

var walk      = require('walk');
var fs        = require('fs');
var _         = require('underscore')._;
var csvtojson = require('csvtojson').core.Converter;

exports.get = function (callback) {

  var csvWalker = walk.walk('./place-csvs-here', {followLinks: false});
  var files = [];
  var ret = [];

  csvWalker.on('file', function (root, stat, next) {
    if (stat.name.match(/[A-Z]+?\-\d+?\.csv/gi)) {
      var filename = root + '/' + stat.name;
      files.push(fs.createReadStream(filename));
    }
    next();
  });

  csvWalker.on('end', function () {
    var left = files.length;
    files.forEach(function (file) {
      var csvConverter = new csvtojson({constructResult: true});

      csvConverter.on('end_parsed', function (data) {
        if (callback) {
          if (--left === 0) {
            // Ensure rows are unique.
            ret = _.uniq(ret, function (x) {
              return JSON.stringify(x);
            });
            // Required fields.
            ret = _.filter(ret, function (x) {
              return (
                 x['Date']    !== undefined
              && x['Balance'] !== undefined
              && x['Date']    !== 'Date'
              && x['Balance'] !== 'Balance'
                );
            });
            callback(ret);
          } else
            ret = ret.concat(data);
        }
      });

      file.pipe(csvConverter);
    });
  });

}

这假设 'end_parsed' 上的 csv 转换器传入的 data 始终是一个数组。它结合所有文件中的数据,然后在执行回调之前对数据运行过滤器。

【讨论】:

  • 啊,我明白你做了什么。说得通。谢谢!不过,另一个快速的问题是,您知道为什么files 将包含例如 5 个项目而列表中的最后一个项目将永远不会真正被解析吗?它总是按字母顺序排列的最后一个。干杯
  • 很难说,您可以尝试只收集文件名并将可读文件流的创建推迟到 forEach() 内部。
猜你喜欢
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 2016-12-29
  • 2017-01-08
  • 2020-06-28
  • 2018-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多