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

NodeJS如何等待多个CSV文件流读取完成后再执行后续处理代码

问题出现原因

该问题核心是Node.js的异步非阻塞执行机制导致的:

  1. fs.createReadStream以及配套的流事件监听(data、end事件)都是异步操作,代码不会等待事件触发完成就会继续往下执行,所以你的readCSV函数会在流还没读完的时候就直接返回空的events数组。
  2. 循环调用readCSV时所有读取任务都是并行触发的,没有等待所有文件读取完成的逻辑,会直接执行后续的processCSV,此时拿到的events要么是空数组,要么是还没填充完成的不完整数据。
  3. 原有代码中循环内部每次用var events覆盖变量,最后调用processCSV时只能拿到最后一次调用readCSV的返回值,无法收集所有文件的数据。
解决方案

核心思路是把readCSV封装为返回Promise的异步函数,再通过async/await + Promise.all等待所有文件读取完成后再执行处理逻辑,改造后的代码如下:

const fs = require('fs');
const csv = require('csv-parser');

// 改造readCSV为返回Promise的异步函数
function readCSV(path) {
  return new Promise((resolve, reject) => {
    const events = [];
    fs.createReadStream(path)
      .pipe(csv())
      .on('data', (row) => events.push(row))
      .on('end', () => {
        console.log('CSV file successfully processed. Length: ' + events.length);
        resolve(events); // 读取完成后返回当前文件的所有数据
      })
      .on('error', (err) => reject(err)); // 捕获读取过程中的错误
  });
}

// 改造app为async异步函数
async function app() {
  try {
    const file_list = listFiles(folder_path);
    // 同时发起所有文件的读取任务,等待全部读取完成
    const allFileData = await Promise.all(file_list.map(file => readCSV(file)));
    // 把所有文件的数组合并为一个数组
    const allEvents = allFileData.flat();
    // 此时所有数据已加载完成,再执行处理逻辑
    processCSV(allEvents);
  } catch (err) {
    console.error('执行出错:', err);
  }
}

app();
Node.js 异步执行时机控制常用方法
  • 回调函数:异步操作完成后调用预先传入的回调函数执行后续逻辑,是最基础的异步控制方式,多层嵌套容易产生回调地狱问题,不推荐复杂场景使用。
  • Promise:ES6 标准提供的异步容器,用来表示异步操作的最终状态和结果,支持链式调用,可解决回调嵌套问题。
  • async/await:基于 Promise 实现的语法糖,可以用类似同步代码的写法编写异步逻辑,可读性极高,await会暂停当前async函数的执行,等待目标 Promise 状态变更后再继续往下执行。
  • 批量异步控制:
    • 等待所有并行异步任务全部完成,使用Promise.all()
    • 只需等待第一个完成的异步任务,使用Promise.race()
    • 需要按顺序逐个执行异步任务,可通过for...of循环配合await逐一执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:24:01