我正在开发一个节点应用程序,我将一个post请求的主体传输到一个可写的流中,该流将数据保存到磁盘。我在构建这个应用程序时意识到,在使用它之前我不知道请求流实际发生了什么。说我做了这样的事情:
app.post('/api/data', (req, res) => {
const writableStream = fs.createWriteStream('data.txt');
setTimeout(() => {
req.pipe(writableStream);
}, 3000);
});
在最初收到请求和流开始传输之间的3秒内,流实际发生了什么?它被加载到内存中了吗?
答案 0 :(得分:2)
Streams支持传入数据的缓冲区,但是当缓冲区填满时,它们会告诉发送方停止发送更多数据,直到它们为更多数据做好准备。
由于传入的请求实际上是TCP连接,而传入的数据是到达TCP连接的数据,因此当您没有按照自己想要的速度读取数据时,这可能会变成更多关于传入TCP数据会发生什么的问题到了。答案是TCP支持流量/控制,接收者告诉发送者暂时停止发送数据,然后当传入缓冲区清除时,它告诉发送者它可以再次开始发送数据。
这是TCP流量控制的quick overview。
在您的特定流编码示例中,在您发出req.pipe()
之前,流上没有数据侦听器,因此它与传入数据无关。因此,它将从传入的TCP流中填充其缓冲区,停止从传入的TCP套接字读取更多(这将触发TCP流控制)。然后,当您运行req.pipe()
时,会自动为data
个事件注册处理程序,并且流将开始触发这些事件。当数据从流缓冲区中读出时,它将能够接受来自TCP套接字的更多传入数据,这将允许TCP告诉TCP套接字的另一端重新启动新数据的传入流,依此类推。 / p>
这里有很多关于可读流的工作原理:http://www.sitepoint.com/basics-node-js-streams/以及它们如何暂停或恢复。