在 node.js 中正确使用 _writev

Posted

技术标签:

【中文标题】在 node.js 中正确使用 _writev【英文标题】:Correct usage of _writev in node.js 【发布时间】:2017-05-11 01:24:15 【问题描述】:

_writev() 在 node.js 中的正确用法是什么? 文档说:

如果流实现能够一次处理多个数据块,则应实现writable._writev() 方法。

它还说:

writable.cork() 的主要目的是避免将许多小数据块写入流不会导致内部缓冲区备份而对性能产生不利影响的情况。在这种情况下,实现writable._writev() 方法的实现可以以更优化的方式执行缓冲写入。

从流实现的角度来看,这没问题。但从可写流消费者的角度来看,writewritev 被调用的唯一方法是通过 Writable.write()writable.cork()

我想看一个小例子来描述实现_writev()的实际用例

【问题讨论】:

"writable._writev() 方法以下划线为前缀,因为它是定义它的类的内部,不应由用户程序直接调用。" nodejs.org/api/… 实现流时,_write 和 _writev 是需要实现的主要功能。 【参考方案1】:

除了write 之外,还可以将writev 方法添加到实例中,如果流包含多个块,则将选择该方法而不是write。例如 Elasticsearch 允许你批量插入记录;因此,如果您正在创建一个 Writable 流来包装 Elasticsearch,那么使用 writev 方法执行单个批量插入而不是多个单独的插入是有意义的,它的效率要高得多。这同样适用,例如 MongoDB 等。

这篇文章(不是我的)展示了一个 Elasticsearch 实现 https://medium.com/@mark.birbeck/using-writev-to-create-a-fast-writable-stream-for-elasticsearch-ac69bd010802

【讨论】:

我对 Nodejs Streams 比较陌生(在一个更复杂的用例中)。这个答案对我帮助很大!谢谢大家。【参考方案2】:

_writev() 将在使用 uncork() 时被调用。节点文档中有一个简单的例子。

stream.cork();
stream.write('some ');
stream.write('data ');
process.nextTick(() => stream.uncork());

更多查看,

https://nodejs.org/api/stream.html#stream_writable_uncork https://github.com/nodejs/node/blob/master/lib/_stream_writable.js#L257

【讨论】:

这不是 _writev 用法的示例,它是使用 cork / uncork 的示例 你可以像 _write 一样定义它。见github.com/nodejs/node/blob/v8.11.1/lib/… 您一直忽略了这一点 - OP 要求“一个描述实际用例的小例子......”,而不是解释它的工作原理或文档链接。我添加了一个更符合我对他们问题的阅读的答案 干得好!我认为使用_write例子很容易,只需将_write替换为_writev

以上是关于在 node.js 中正确使用 _writev的主要内容,如果未能解决你的问题,请参考以下文章

在 Node.js 中使用 async/await 正确处理错误

在 node.js 中计算 Content-length 标头的正确方法是啥

如何正确配置实验性 ECMAScript 模块,以便在 Node.js 中使用导入/导出

如何在 linux 服务器的 80 端口上启动 node.js?

在 Node.js 中进行同步 MongoDB 查询的正确方法是啥?

使用node.js编写前端代码资源文件.jpg.css报错404