JavaScript异步函数未等待文件系统操作完成问题求助
Node.js 目录文件信息读取异步问题修复
问题描述
尝试编写函数实现读取指定目录、遍历文件并将文件信息存入数组,但遇到以下问题:
- 文件信息的
console.log能正常输出正确内容 newFunc末尾的console.log({response})输出空数组- 用
await调用newFunc得到的getFileData也为空 - 给异步函数加超时后能拿到正确结果,说明代码未等待文件读取操作完成
原实现代码
目录读取函数newFunc
const newFunc = async () => { let response: any = []; fs.readdir("files", function (err, files) { if (err) { console.error("Could not list the directory.", err); process.exit(1); } for (const file of files) { fs.stat(`files/${file}`, (err, stats) => { if (err) { throw err; } // print file information console.log(`File Data Last Modified: ${stats.mtime}`); console.log(`File Status Last Modified: ${stats.ctime}`); console.log(`File Status Last Modified: ${stats.size}`); console.log({ file }); response.push({ fileName: file, updatedAt: stats.mtime, createdAt: stats.ctime, size: stats.size, }); }); } }); console.log({ response }); return response; };
Node.js 端点代码
const getFileData = await newFunc(); console.log({getFileData}) res.status(200).json(getFileData);
问题原因
代码使用了fs模块的回调式异步API(fs.readdir和fs.stat),这类API不会阻塞代码执行,也无法被async/await直接等待。newFunc函数在触发fs.readdir后,立刻执行了console.log({ response })并返回空数组,此时文件读取和统计的异步操作还未完成,自然无法得到数据。
修复方案
改用fs.promises提供的Promise风格API,配合async/await实现异步等待,同时用Promise.all并行处理多个文件的统计操作,确保所有异步完成后再返回结果。
修复后的代码
// 导入fs的promise版本 const fs = require('fs').promises; const path = require('path'); const newFunc = async () => { try { // 等待目录读取完成 const files = await fs.readdir("files"); // 并行处理所有文件的stat操作 const response = await Promise.all(files.map(async (file) => { const filePath = path.join("files", file); const stats = await fs.stat(filePath); // 打印文件信息(可选) console.log(`File Data Last Modified: ${stats.mtime}`); console.log(`File Status Last Modified: ${stats.ctime}`); console.log(`File Size: ${stats.size}`); console.log({ file }); return { fileName: file, updatedAt: stats.mtime, createdAt: stats.ctime, size: stats.size, }; })); console.log({ response }); return response; } catch (err) { console.error("Could not process directory or files.", err); // 避免直接中断服务,抛出错误交由上层处理 throw err; } };
端点代码无需修改
const getFileData = await newFunc(); console.log({getFileData}) res.status(200).json(getFileData);
内容的提问来源于stack exchange,提问作者Floky99
相关产品推荐
相关产品推荐

