注释掉 on('data') 请求为什么一直挂着?― 了解 Node.js Stream 的两种模式
这是来自「Nodejs技术栈」交流群一位读者朋友提的一个问题,“如果注释掉 req.on('data') 事件监听,end 事件就收不到了,进而永远也不会执行 res.end(),请求会被一直挂着,为什么?”。
如果你读到这里,也可以先思考下这个问题!
const http = require('http'); http.createServer((req, res) => { let dat注释a = ''; // req.on('data', chunk => { // data += chunk.toString(); // }); req.on('end', () => { res.end掉 (data); }); }).listen(3000);
Node.js 的可读流对象提供了两种模式:流动模式(flowing)、暂停模式(paused),如果你使用管道 pipe() 或异步迭代可能不会关注到这个问题,在它们的内部实现中已经处理好了,如果你是基于事件的 API 来处理流,可能会有这些疑问。
流动模式(flowing)
流动模式下数据自动从底层系统获取,并通过 EventEmitter 提供的事件接口,尽可能快的提供给应用程序。需要注意的是所有的可读流一开始都处于暂停模on式,要切换为流动模式,可通过以下几种方式实现:
一:注册 'data' 事件
为可读流对象注册一个 'data' 事件,传入事件处理函数,会把流切换为流动模式,在数据可用时会立即把数据块传送给注册的事件处理函数。
这也是上面的疑问,为什么注释掉 'data' 事件,请求就会一直被挂起。
req.on('data', chunk => { data += chunk.toString(); }); 二:stream.pipe() 方('法
调用 pipe() 方法将数据发送到可写流。
readable.pipe(writeable)
可读流的 pipe() 方法实现中也是注册了 'data' 事件,一边读取数据一边写入数据至可写流。可以参见笔者之前的这篇文章 Node.js Stream 模块 pipe 方法使用与实现原理分析。
Readable.prototype.pipe = function(dest, options) { const src = thisda; src.on('data', ondata); function ondata(chunk) { const ret = dest.write(chunk); if (ret === false) { &tanbsp; ... src.pause(); } } ... }; 三:stream.resume() 方法
stream.resume() 将处于暂停模式的可读流,恢复触发 'data' 事件,切换为流动模式。
对一开始的示例做一个改造,先调用 stream.re')sume() 用来耗尽流中的数据,但此时没有做任何的数据处理,之后会收到 end 事件。
const http = require('http'); http.createServer((req, res) => { req.resume(); req.on('end', () => {   请; res.end('Ok!'); }); }).listen(3000); 四:异步迭代
无需注册事件监听函数,使用 for...await of 遍历可读流,写法上也很简单。下例,因为用到**顶级 await 特性,**需要在 ES Modules 规范中使用。
// app.mjs import { createServer as server } from 'http';&nb求为sp;import { on } from 'events'; const ee = on(server().listen(3000), 'request'); for await (const [{ url }, res] of ee) { res.end('OK!');&什么nbsp;}
暂停模式
暂停模式也是流一开始时所处的模式,该模式下会触发 'readable' 事件,表示流中有可读取的数据,我们需要不断调用 read() 方法拉取数据,直到返回 null,表示缓冲区中的数据已被耗尽,在 read() 返回 null 后,会再次触发 'readable' 事件,表示仍有可读取的数据,如果此时停止 read() 方法调用,同样的请求也会被挂起。
stream.read(size) 方法从流缓冲区拉取数据,每次返回指定 size 大小的数据,如果不指定 size 则返回内部所有缓冲的数据。
const http&一直nbsp;= require('http'); http.createServer((req, res) => { let data = ''; let chunk; req.on('readable', () => { w挂着hile (null !== (chunk = req.read())) { data += chunk.toString(); } }) req.on('end', () => {&nbs?―p; res.end(data); }); }).listen(3000);
背压问题思考??
以流的形式从可读流拉取数据到可写流,通常**从磁盘读取数据的速度比磁盘写入的速度是快的,如果可写流来不及消费数据造成数据积压(专业术语会称呼这个问题为 “背压”)会怎么样?**也是来自「Nodejs技术栈」交流群读者朋友的疑问,可以思考下,答案可以写在评论区,感兴趣的关注下「Nodejs技术栈」下一次讲解。
总结
流刚开始处于暂停模式, 了所以注释掉 req.on('data') 事件监听,请求才会一直挂起。在基于流的方式读取文件时,之前通常使用注册 'data' 事件处理函数的方式从可读流中拉取数据,现在 Node.js 支持了异步迭代,更推荐你使用 for...await of 这种方式来读取数据,代码看起来也会更简洁,同步编码思维让人也能更好的理解。
(责任编辑:技术博客)
-
云梦级1月16日云梦级消息,据京东物流黑板报透露,近日,荣耀宣布 2025 年在沙特手机出货量已突破 200 万台,目前京东物流已携手荣耀在中东构建多个海外仓库,是荣耀在中东最大的供应链物流服务商之一...[详细]
-
4月26日消息,阿里云宣布史上最大规模降价,核心产品价格全线下调15%至50%,存储产品最高降幅达50%。 此次阿里云降价的产品中,弹性计算7代实例和倚天实例降价最高20%,存储OSS深度冷归档相比此...[详细]
-
ChatGPT 移动应用收入已突破 20 亿美元,竞争对手远远落后
根据应用情报提供商 Appfigures 的最新分析,自2023年5月推出以来,OpenAI 的 ChatGPT 移动应用在全球消费者支出中已经达到了惊人的20亿美元。这一收入数字是其竞争对手 Cla...[详细]
-
云梦级4月15日云梦级消息,2026年4月14日,百济神州(上交所代码:688235.SH;香港联交所代码:06160.HK;纳斯达克代码:ONC)发布A股2025年度报告。 报告期内,公司营业总收入...[详细]
-
作者|张宇 编辑|杨博丞 图源|IC photo 中国汽车工业协会的统计数据显示,2026年前两个月,中国汽车出口延续了此前强劲增长态势,累计出口量达135.2万辆,同比大幅增长48.4%。其中,2月...[详细]
-
美国会周五举行“谷歌FB垄断媒体业”听证会 微软加入“控诉”方
新浪科技讯 北京时间3月10日早间消息,据报道,3月12日,美国国会众议院将举行一场听证会,聚焦谷歌和Facebook两大公司对新闻传媒行业的主导影响力,令人意外的是,微软高管也将出席听证会。 之前,...[详细]
-
云梦级11月27日云梦级消息,据财闻报道,中国家具品牌顾家家居(603816.SH)的前控股股东顾家集团(现更名“杭州德烨嘉俊企业管理有限公司”)在进入破产重整程序后,遭债权人向地方政府举报,指控公司...[详细]
-
2月23日消息,今日晚间,阿里巴巴集团发布了截至12月31日的2023财年第三季度未经审计财报。 财报显示,按照美国通用会计准则(GAAP)计算,阿里第三财季营收为2477.56亿元(人民币,下同)(...[详细]
-
题目 :打印出杨辉三角形(要求打印出10行如下图)。 程序分析 :杨辉三角,是二项式系数在三角形中的一种几何排列 每个数等于它上方两数之和。 每行数字左右对称,由1开始逐渐变大。 第n行的数字有n项。...[详细]
-
猕猴桃熟了能放冰箱吗-九州醉餐饮网猕猴桃熟了可以放在通风的阴凉处保存,也可以放在冰箱里保存,但是熟了的猕猴桃要比生的猕猴桃存放的时间要短,熟了的猕猴桃更容易变质、腐烂,产生异。猕猴桃熟了可以放冰箱吗-...[详细]
- https://www.lee.com/search?q=谷歌快排操作流程【tg:seogoogle987】,aDZ
- https://www.livehindustan.com/tags/谷歌快排操作流程【tg:seogoogle987】,FDz
- https://www.teamlab.art/pt/?submit=谷歌快排操作流程【tg:seogoogle987】,9ia
- https://www.unclefossil.com/search/谷歌快排操作流程【tg:seogoogle987】gad_source=1&gclid=Cj0KCQjw_-GxBhC1ARIsADGgDjsNKplUXa2F6YGlHBK2sHDQ88cgsJBb05DyO99TV9jNq_cT0kGMqyQaAgHQEALw_wcB
- https://www.skicheck.at/en/?action=CHECK&s=谷歌快排操作流程【tg:seogoogle987】,334
- https://www.paxnet.co.kr/search/jongmok?kwd=谷歌快排操作流程【tg:seogoogle987】0Dj
- https://www.qylaws.com/search/谷歌快排操作流程【tg:seogoogle987】,YJT
- https://store.line.me/search/sticker/ja?q=谷歌快排操作流程【tg:seogoogle987】1sU
- https://www.schenckprocess.com/search?q=谷歌快排操作流程【tg:seogoogle987】,ABJ
- https://www.tycoonstory.com/?s=谷歌快排操作流程【tg:seogoogle987】,Cx6

云安全日报210322:Debian云虚拟化工具发现信息泄露漏洞,需要尽快升级
标签: 字节 Seedance 2.0 即梦AI 豆包
标签: 鹿客科技 智能锁 静脉锁 百度
二值化每个特征,微软用1350亿参数稀疏神经网络改进搜索结果
外媒:美国国防部正考虑终止与微软的百亿美元云计算合同
