You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript 使用 csvtojson 读取目录多CSV文件返回客户端的异步问题

核心问题定位

当前代码存在异步执行时序错位:

  • Array.prototype.forEach 不具备异步等待能力,即便回调函数用async修饰,forEach本身也不会阻塞等待所有回调内部的Promise执行完成
  • 调用fetchData()时,代码仅会把所有CSV转JSON的异步任务排入事件队列,不会等待任务执行结束,就直接运行到res.send(jsonData)逻辑;此时jsonData数组还未填充任何转换结果,因此返回给客户端的是空数据。
修正实现方案

具体调整逻辑如下:

  • 将原有forEach遍历替换为map遍历,把每个文件的CSV转换操作封装为独立的Promise对象
  • 使用Promise.all并行等待所有文件的处理任务完成,拿到全量数据后再执行响应返回
  • 把路由接口的回调函数改造为async函数,支持await阻塞后续同步逻辑
  • 补充try/catch异常捕获,避免异步流程中的错误导致接口无响应或进程崩溃

修正后的完整代码如下:

router.get("/covidData/", async (req, res) => {
  try {
    const jsonData = [];
    // 保留原有目录读取逻辑
    const files = fs.readdirSync(__dirname.replace("routes", "public/covidData"));

    // 为每个文件生成独立的异步处理Promise
    const fileProcessTasks = files.map(async (file) => {
      const currentFilePath = __dirname.replace("routes", "public/covidData/" + file);
      return await csvtojson({
        includeColumns: /Date Announced|Detected State|Current Status/,
      }).fromFile(currentFilePath);
    });

    // 等待所有文件的转换任务全部完成
    const processResults = await Promise.all(fileProcessTasks);
    // 合并所有文件返回的JSON数组
    jsonData.push(...processResults.flat());

    // 全量数据加载完成后再返回响应
    res.send(jsonData);
  } catch (error) {
    res.status(500).send({
      message: "CSV数据读取失败",
      errorDetail: error.message
    });
  }
});
补充注意事项
  • 不要在无等待能力的循环中嵌套async操作:forEach、普通同步for循环如果内部嵌套await逻辑,都会出现本次遇到的时序错位问题
  • 如果需要提升单文件处理的错误容忍度(即某个文件读取失败不影响其他文件的数据返回),可以将Promise.all替换为Promise.allSettled,遍历返回结果时筛选出状态为fulfilled的成员做数据合并
  • 相比串行逐文件读取的模式,Promise.all的并行处理逻辑可以大幅降低多文件读取的总耗时

内容的提问来源于stack exchange,提问作者atulsmania

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 10:45:05