为何我的async/await实现无效?Fast-CSV解析CSV返回空数组
问题原因分析
你的代码里log(data)始终输出空数组的核心原因是传入的行处理函数没有返回值:
- 调用
readCsv时,你传的第三个参数是(row) => {},这个空函数默认返回undefined - 在
readCsv内部,const obj = rowProcessor(row)得到的是undefined,if (obj)条件不成立,因此没有任何行数据被push到data数组中,最终resolve(data)返回的自然是空数组
另外还有一个次要问题:files.forEach(async (file) => {})中的异步操作不会被forEach等待,这虽然不是导致空数组的直接原因,但会影响后续逻辑的执行顺序。
解决方案
1. 修复行处理函数的返回值
如果你不需要对行数据做任何处理,直接返回原行数据即可,修改调用readCsv的代码:
files.forEach(async(file) => { // 将空函数改为返回row的函数 const data: any = await readCsv(`${inArg}/${file}.csv`, { headers: true }, (row) => row) log(data) // 后续业务逻辑 })
如果需要自定义处理行数据,就在行处理函数里返回处理后的对象:
const data: any = await readCsv(`${inArg}/${file}.csv`, { headers: true }, (row) => { // 示例:只保留特定字段 return { id: row.id, username: row.username } })
2. 优化异步遍历逻辑(可选)
forEach不会等待异步函数执行完成,如果你需要按顺序处理文件,或者等待所有文件处理完成后做后续操作,建议改用for...of循环:
// 替换原来的files.forEach for (const file of files) { const data: any = await readCsv(`${inArg}/${file}.csv`, { headers: true }, (row) => row) log(data) // 后续业务逻辑 }
如果想并行处理所有文件,用Promise.all提升效率:
const allData = await Promise.all( files.map(file => readCsv(`${inArg}/${file}.csv`, { headers: true }, (row) => row)) ) log(allData) // 所有文件的数据集合数组
3. 增强readCsv的容错性(可选)
可以在readCsv函数里处理行处理函数返回undefined的情况,默认保留原行数据:
function readCsv(path: string, options: ParserOptionsArgs | undefined, rowProcessor: (arg0: any) => any) { return new Promise((resolve) => { const data: any = [] parseFile(path, options) .on('data', (row: any) => { const obj = rowProcessor(row) // 若行处理函数未返回值,则直接使用原行数据 data.push(obj !== undefined ? obj : row) log(obj || row) }) .on('end', () => { resolve(data) log('Done') }) }) }
内容的提问来源于stack exchange,提问作者Elmar B.
相关产品推荐
相关产品推荐

