Node.js可写流和drain事件

9
write()方法的文档表示:
返回false表示内核缓冲区已满,数据将在未来发送。
drain事件的文档表示:
在write()方法返回false后,会触发此事件以指示可以再次安全地写入。
这是什么意思?我需要等待drain事件才能再次写入吗?我试图写入的数据发生了什么?它会丢失吗?如果我调用write而不等待drain事件会发生什么?
2个回答

7

@TooTallNate的回答是错误的。你绝对应该关注.write的返回值。

这是什么意思?我必须等待drain事件才能再次写入吗?

是的,当.write返回false时,你必须等待。

我试图写入的数据发生了什么?它丢失了吗?

不,它没有丢失,按正确的顺序缓存了下来。

如果我在等待drain事件之前调用写入操作会发生什么?

如果你没有正确处理drain事件,你的脚本将阻塞事件循环,并最终耗尽内存限制,导致应用程序崩溃。

我在另一个问题中给出了详细的解释:为什么尝试写入大文件会导致js堆栈耗尽内存?


4
您可以安全地调用write()而不必担心返回值。 当内核缓冲区已满时,Node将缓冲任何写入调用,并按您预期的顺序推送它们。 在再次编写之前,您不需要等待'drain'事件。
可选地,您可以检查write()的返回值,然后通知正在向流中写入内容的对象,缓冲区已满。 这正是Stream#pipe()所做的事情。
因此,通常只需使用Stream#pipe()即可自动处理所有好处 :)

1
如果在用户内存中缓冲res.write(即未刷新到内核缓冲区)时调用process.exit()会发生什么?响应是否会丢失? - Emmett
@Emmett 是的,如果在仍有缓冲写入调用需要刷新时调用 process.exit(),那么这些数据将会丢失。 - TooTallNate
8
“不关心write()的返回值可能存在一定的安全隐患。”当前文档指出:“虽然允许在不排空数据流的情况下调用write(),但 Node.js 会缓存所有写入的数据块,直到内存使用达到最大值,此时它将无条件地中止。即使在它中止之前,高内存使用也会导致垃圾回收性能不佳和高 RSS(通常即使在不再需要内存后,也不会释放给系统)。” 另请参阅:https://dev59.com/QVoU5IYBdhLWcg3wTV3E - TachyonVortex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接