如何对fs.readFile使用await?调用后结果数组为空如何解决?
问题原因
你使用的fs.readFile()是异步回调式API,执行parseProviders()时只会触发文件读取任务,不会等待回调函数执行就会立刻运行后续的console.log(domains),此时文件尚未读取完成,domains数组还没有被填充数据,所以打印结果为空。只有等主线程同步任务执行完、文件读取完成后,回调函数才会执行,此时domains才有正确值。
修复方案
推荐用Node.js内置的fs promise API配合async/await改写,避免回调嵌套问题,同时优化原有逻辑避免匹配不到行时抛出全局错误:
const fs = require("fs/promises"); const re = /@(.*?):/; // 异步函数返回处理后的域名数组,避免全局变量污染 const parseProviders = async () => { const domains = []; const data = await fs.readFile("file.txt"); data .toString() .split("\n") .forEach((line) => { const matchRes = line.match(re); // 先判断匹配结果,避免不匹配的行触发报错 if (matchRes && matchRes[1] && !domains.includes(matchRes[1])) { domains.push(matchRes[1]); } }); return domains; } // 自执行函数声明为async,用await等待异步任务完成 (async () => { const domains = await parseProviders(); console.log(domains); // 可正常打印非重复域名数组 })();
可选优化
- 若文件行数较多,用
Set去重性能远高于数组includes判断:
const parseProviders = async () => { const domainSet = new Set(); const data = await fs.readFile("file.txt"); data .toString() .split("\n") .forEach((line) => { const matchRes = line.match(re); if (matchRes?.[1]) domainSet.add(matchRes[1]); }); return Array.from(domainSet); }
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

