使用Promises/Async/Await在Node.js中读取目录多文件遇问题
解决批量读取文件时的Promise pending与未处理拒绝错误
问题根源
你的代码存在两个核心问题:
map生成的Promise数组未被正确等待:await dirFilesArr.map(...)实际是在等待一个普通数组(而非Promise),导致内部readFilePro返回的Promise始终处于pending状态,且错误无法被外层try/catch捕获,触发UnhandledPromiseRejection。- 文件路径错误:直接传入文件名给
readFilePro,Node.js会以当前工作目录为基准查找,而非你指定的textFileDir,这才是"Could not find file"错误的真正原因。
修复后的代码(贴近原有实现)
import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const textFileDir = `${__dirname}/files/`; const readDirPro = (dir) => { return new Promise((resolve, reject) => { fs.readdir(dir, (error, files) => { if (error) reject('Could not find directory'); resolve(files); }); }); }; const readFilePro = (file) => { return new Promise((resolve, reject) => { fs.readFile(file, 'utf-8', (err, data) => { if (err) reject(`读取文件失败: ${err.message}`); resolve(data); }); }); }; const readAllFiles = async () => { try { const dirFilesArr = await readDirPro(textFileDir); // 修复点1:用Promise.all等待所有文件读取完成,同时拼接完整路径 const fileContents = await Promise.all( dirFilesArr.map(file => { const fullFilePath = path.join(textFileDir, file); return readFilePro(fullFilePath); }) ); // 按最终目标生成JSON文件 const resultJson = JSON.stringify( dirFilesArr.map((fileName, index) => ({ fileName, content: fileContents[index] })), null, 2 ); fs.writeFileSync(path.join(__dirname, 'result.json'), resultJson); return '所有文件读取完成,已生成result.json'; } catch (err) { console.log(`错误: ${err}`); throw err; } }; (async () => { try { console.log('开始读取所有文件!'); const x = await readAllFiles(); console.log(x); console.log('完成!'); } catch (err) { console.log(`执行错误 💥: ${err}`); } })();
关键修改说明
Promise.all处理异步数组:map返回由readFilePro生成的Promise数组,Promise.all会等待所有Promise完成(或任一失败),将结果收集到fileContents中,同时让外层try/catch能捕获所有错误。- 拼接完整文件路径:用
path.join(textFileDir, file)确保Node.js能准确定位到目标目录下的文件,解决"找不到文件"的核心问题。 - 新增JSON生成逻辑:按照你的最终目标,将文件名与对应内容整理成JSON结构并写入文件。
修复后控制台输出
执行后会正常输出:
开始读取所有文件! 所有文件读取完成,已生成result.json 完成!
若路径或文件存在错误,错误会被外层try/catch捕获并输出对应信息,不会再出现UnhandledPromiseRejection。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

