CSV异步读取与数据使用问题:顶层无法使用await获取数据
解决顶层await无法使用的问题
首先说明你最初写法的问题:你第一次的代码里,流是异步执行的,on("end")回调里的return entries无法把值传递到外部——外部的entries变量在流处理完成前就被读取了,自然拿不到正确结果。你改用async函数结合stream/promises.finished的思路是对的,下面是三种解决顶层await限制的方法:
方法1:用立即执行异步函数(IIFE)包裹
这是最无需修改项目配置的方案,直接把需要使用await的代码放到一个自执行的异步函数里:
const fs = require("fs"); const { parse } = require("csv-parse"); const { finished } = require("stream/promises") const storeSandwiches = async () => { const entries = []; const parser = fs .createReadStream("./sandwiches.csv") .pipe(parse({ delimiter: ",", from_line: 1 })); parser .on("readable", function () { let record; while ((record = parser.read()) !== null) { entries.push(new Sandwich(record[0], record[1])); } }) .on("error", function (error) { console.log(error.message); }); await finished(parser); return entries; }; // 自执行异步函数处理顶层await (async () => { try { const sandwiches = await storeSandwiches(); // 在这里写你的三明治成本计算逻辑,比如: const totalCost = sandwiches.reduce((sum, sandwich) => sum + sandwich.cost, 0); console.log("总成本:", totalCost); } catch (err) { console.error("读取CSV出错:", err); } })();
方法2:切换为ES模块(原生支持顶层await)
Node.js的ES模块(ESM)允许直接使用顶层await,有两种开启方式:
- 修改文件后缀:把你的脚本文件后缀从
.js改成.mjs,然后调整导入语法为ES模块格式:
// 文件名:sandwiches.mjs import fs from "fs"; import { parse } from "csv-parse"; import { finished } from "stream/promises"; const storeSandwiches = async () => { // 函数内容和之前一致 }; // 直接使用顶层await const sandwiches = await storeSandwiches(); // 后续成本计算逻辑 const totalCost = sandwiches.reduce((sum, sandwich) => sum + sandwich.cost, 0); console.log("总成本:", totalCost);
- 修改package.json:在项目根目录的
package.json中添加"type": "module"字段,这样所有.js文件都会被当作ES模块,无需修改后缀即可使用顶层await。
方法3:使用Promise的.then()回调(兼容旧环境)
如果你不想用async/await,也可以通过Promise的链式调用获取结果:
storeSandwiches() .then(sandwiches => { // 在这里处理数据、计算成本 const totalCost = sandwiches.reduce((sum, sandwich) => sum + sandwich.cost, 0); console.log("总成本:", totalCost); }) .catch(err => { console.error("读取CSV失败:", err); });
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

