Express中带配置的csvtojson多次请求报write after end错误如何解决
问题原因
你当前代码在全局作用域初始化了converter实例,csvtojson的转换器实例本质是单次可写流,第一次请求调用fromFile执行完成后,流就已经被关闭销毁了,后续请求复用同一个已关闭的实例调用文件读取方法,就会触发write after end报错。
解决方案
方案1:抽离配置,每次请求新建实例
该方案为通用方案,无论CSV文件是否会动态更新都可以使用。你只需要把配置抽为公共常量,每次接口请求时用该配置新建转换器实例即可,完全保留你需要的配置参数:
const express = require('express'); const router = express.Router(); const csv = require('csvtojson'); // 抽离公共配置,无需重复编写 const csvConfig = { noheader: true, delimiter: ',', headers: ['date', 'time', 'point1', 'point2', 'point3', 'point4', 'point5'] }; router.get('/get-sample', (req, res) => { // 每次请求新建转换器实例,不会出现流已关闭的问题 csv(csvConfig).fromFile('./file.csv').then((jsonObj) => { res.send(jsonObj); }).catch(err => { // 补充错误捕获,避免未处理异常导致服务崩溃 res.status(500).send('数据读取失败'); console.error(err); }); });
方案2:预解析缓存数据(适合CSV文件固定不变的场景)
如果你的./file.csv是不会动态修改的静态文件,可以在服务启动时就把文件解析为JSON缓存起来,接口直接返回缓存结果即可,无需每次请求都读文件解析,性能更高:
const express = require('express'); const router = express.Router(); const csv = require('csvtojson'); let cachedJson = null; // 服务启动阶段预解析CSV文件 csv({ noheader: true, delimiter: ',', headers: ['date', 'time', 'point1', 'point2', 'point3', 'point4', 'point5'] }).fromFile('./file.csv').then(jsonObj => { cachedJson = jsonObj; }).catch(err => { console.error('CSV文件预解析失败', err); }); router.get('/get-sample', (req, res) => { if (cachedJson) { res.send(cachedJson); } else { res.status(503).send('数据暂未准备完成,请稍后重试'); } });
内容的提问来源于stack exchange,提问作者UnknownInnocent
相关产品推荐
相关产品推荐

