Node.js中require('fs')与require('fs').promises的差异及引入疑问
Node.js中
fs模块与fs.promises的差异解析 你遇到的情况本质是Node.js的fs模块提供了两套不同风格的API,分别对应不同的异步编程模式:
1. require('fs'):回调式API集合
这是fs模块的默认导出,所有方法都基于回调函数设计:
- 比如传统的文件读写写法是
fs.readFile(path, (err, data) => { /* 处理结果或错误 */ }) - 流式操作方法(
createWriteStream、createReadStream等)只存在于这个API集合里——因为流本身是事件驱动的异步模式,它的使用逻辑是通过监听data、end、error等事件来处理,和Promise的一次性异步结果模式不匹配,所以没有被放到Promise化的API里 - 你觉得“不带.promises的fs无法使用
writeFile”是个误解:回调式API里其实有fs.writeFile,只是它需要传入回调函数,不能直接用await,比如:fs.writeFile(TOKEN_PATH, payload, (err) => { if (err) throw err; console.log('文件写入完成'); });
2. require('fs').promises:Promise式API集合
这是Node.js为了适配async/await语法,专门提供的Promise化版本API:
- 所有方法都返回Promise对象,可以直接配合
await使用,这也是你在saveCredentials里用await fs.readFile和await fs.writeFile能正常工作的原因 - 这个API只包含可以被Promise化的“一次性异步操作”方法(比如文件读写、目录创建、文件状态查询等),流式操作不在其中,因为流的事件驱动模式无法被简单包装成Promise
为什么需要两次引入?
你的代码同时用到了两种API:
saveCredentials里需要用async/await简化异步逻辑,所以依赖Promise式APIdownloadFile里需要创建写入流,而流式方法只存在于回调式API中
不过其实不需要重复引入模块,Node.js模块是缓存的,你可以只引入一次,然后分别调用两个API集合,写法更简洁:
const fs = require('fs'); const fsPromises = fs.promises; // 用fsPromises做Promise式操作 await fsPromises.readFile(CREDENTIALS_PATH); // 用fs做流式操作 const fileStream = fs.createWriteStream("test.txt");
内容的提问来源于stack exchange,提问作者Linda Lawton - DaImTo
相关产品推荐
相关产品推荐

