Node.js 9.3.0_1在MacOS上listener参数类型错误问题排查
咱们一步一步来解决你的问题,先拆解第一个错误,再搞定文件为空的问题:
第一个错误:ERR_INVALID_ARG_TYPE 的根源
你在close事件回调里写file.close()是完全错误的操作。当close事件触发时,文件流已经处于关闭(或正在关闭)的状态,此时调用file.close()会触发循环调用——file.close()会再次触发close事件,无限往复。而在Node.js 9.3.0这个版本里,这种异常的调用会导致内部处理监听器时参数出错,也就是你看到的那个类型错误。
第二个问题:文件为空的原因
你把response.pipe(file)放在了response的data事件回调里,这是典型的误用。pipe()方法本身会自动绑定data事件来处理数据传输,当你在data事件里重复调用pipe(),会让流的处理逻辑彻底混乱,最终根本无法正确写入数据到文件中。
修正后的完整代码
const fs = require('fs'); const https = require('https'); // 创建文件写入流 const file = fs.createWriteStream("data/test.txt"); const httpOptions = "https://google.com"; const req = https.request(httpOptions, (response) => { // 直接在这里调用pipe,它会自动处理所有数据传输逻辑 response.pipe(file); // 监听文件流的finish事件:所有数据写入完成时触发 file.on("finish", () => { console.log("文件内容写入完成"); }) // 监听文件流的错误 .on("error", (err) => { console.error("文件写入出错:", err); file.destroy(err); // 出错时销毁流,释放资源 }); // 可选:监听响应流的结束事件,确认服务器数据发送完毕 response.on('end', () => { console.log("服务器响应数据已全部接收"); }); }); // 监听请求本身的错误 req.on('error', (e) => { console.error("请求发送出错:", e); file.end(); // 请求出错时,关闭文件流避免资源泄漏 }); req.end();
关键要点说明
- 正确使用
pipe():pipe()是Node.js流处理的核心方法,它会自动帮你处理data、end事件,以及数据的缓存、背压处理,绝对不要把它放在data事件回调里。 - 不要手动调用
file.close():当响应流结束时,pipe()会自动调用file.end(),触发finish事件后,文件流会自行关闭,触发close事件。你只需要监听这些事件做后续处理即可,手动调用close()反而会出问题。 - 全面的错误处理:覆盖请求、响应、文件流的所有错误场景,确保出现异常时能正确释放资源,避免内存泄漏或损坏文件。
内容的提问来源于stack exchange,提问作者JavaRunner
相关产品推荐
相关产品推荐

