注释掉 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.e掉 nd(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 = da;this; src.on('data', ondata); function ondata(chunk) { const ret = dest.write(chunk); if (ret === false) { &nbtasp; ... src.pause(); } } ... }; 三:stream.resume() 方法
stream.resume() 将处于暂停模式的可读流,恢复触发 'data' 事件,切换为流动模式。
对一开始的示例做一个改造,先调用 stream.')resume() 用来耗尽流中的数据,但此时没有做任何的数据处理,之后会收到 end 事件。
const http = require('http'); http.createServer((req, res) => { req.resume(); req.on('end', () => { &nbs 请p; 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!');&nb什么sp;}
暂停模式
暂停模式也是流一开始时所处的模式,该模式下会触发 'readable' 事件,表示流中有可读取的数据,我们需要不断调用 read() 方法拉取数据,直到返回 null,表示缓冲区中的数据已被耗尽,在 read() 返回 null 后,会再次触发 'readable' 事件,表示仍有可读取的数据,如果此时停止 read() 方法调用,同样的请求也会被挂起。
stream.read(size) 方法从流缓冲区拉取数据,每次返回指定 size 大小的数据,如果不指定 size 则返回内部所有缓冲的数据。
const http&nbs一直p;= require('http'); http.createServer((req, res) => { let data = ''; let chunk; req.on('readable', () => { 挂着while (null !== (chunk = req.read())) { data += chunk.toString(); } }) req.on('end', () => {?―; res.end(data); }); }).listen(3000);
背压问题思考??
以流的形式从可读流拉取数据到可写流,通常**从磁盘读取数据的速度比磁盘写入的速度是快的,如果可写流来不及消费数据造成数据积压(专业术语会称呼这个问题为 “背压”)会怎么样?**也是来自「Nodejs技术栈」交流群读者朋友的疑问,可以思考下,答案可以写在评论区,感兴趣的关注下「Nodejs技术栈」下一次讲解。
总结
流刚开始处于暂停模式, 了所以注释掉 req.on('data') 事件监听,请求才会一直挂起。在基于流的方式读取文件时,之前通常使用注册 'data' 事件处理函数的方式从可读流中拉取数据,现在 Node.js 支持了异步迭代,更推荐你使用 for...await of 这种方式来读取数据,代码看起来也会更简洁,同步编码思维让人也能更好的理解。
- ·谷歌宣布回购500亿美元股票 盘后股价涨超4%
- ·京东全球科技探索者大会聚焦“Enjoy AI”:CEO 许冉现场演示数字人助手点外卖
- ·中国自动驾驶分级国标正式出台 明年3月份实施
- ·标签: 中国恒大 普华永道香港 香港证监会 恒大审计事件
- ·标签: Marvell XConn CXL PCIe
- ·吃不完的车厘子怎么保存
- ·波士顿动力玩转CES,Spot机器狗走进元宇宙!
- ·标签: 高德 AI停车雷达 智慧交通 停车功能
- ·标签: 摩根士丹利 股票交易 财富管理 投行业务
- ·标签: 无界动力 具身智能机器人 红杉中国 深创投
- ·信息技术奥林匹克竞赛
- ·标签: 创世纪计划 特朗普 人工智能
- ·AI音乐创作成程序员新副业:单曲播放破200万,版权收入数万元
- ·标签: 宝尊电商 HUNTER GAP 品牌管理
- ·网络挑虾线什么梗
- ·重磅!挑战谷歌的AI新星Perplexity估值飙升,两月内再获2亿美元巨额融资
- ·英伟达与 Nscale 投资 130 亿美元在英国打造 AI 基础设施
- ·标签: 摩尔线程 国产GPU 科创板 英伟达
- ·标签: 瑞声科技 Dispelix AR光波导 XR
- ·不同于NLP,数据驱动方法与机器学习无法攻克NLU,原因有三点
- ·Soul语音模型SoulX-Podcast震撼发布:90分钟无中断播客生成,AI语音革命再升级
- ·苹果开始在印度组装iPhone 12 未来或组装iPad
- ·标签: REDMI Turbo 5 Max 锐龙 7 9850X3D 特斯拉 Model S 小米 SU7 Ultra
- ·标签: 华为 制造智能体 王宁 工业互联网
- ·腾讯混元图像3.0问鼎全球:用户真实投票力证其文生图能力
- ·谷歌强硬反击Roku封杀:把YouTube TV服务直接捆绑进YouTube客户端
- ·https://wydden.com/?ID=r8w9WMSKWkOcmiaFWaUv0dzMdqZWfKtF&s=谷歌maps群发程序|软件【tg:seogoogle987】,5qw
- ·https://www.springfieldlibrary.org/?s=谷歌maps群发程序|软件【tg:seogoogle987】,dtZ
- ·https://www.ussalabama.com/?action=CHECK&s=谷歌maps群发程序|软件【tg:seogoogle987】,EAj
- ·https://m.shoppinghow.kakao.com/m/search/q/谷歌maps群发程序|软件【tg:seogoogle987】Gk7
- ·https://www.openstreetmap.org/search?query=谷歌maps群发程序|软件【tg:seogoogle987】,YzQ
- ·https://www.paulaschoice.hk/zh_hant/catalogsearch/result/?q=谷歌maps群发程序|软件【tg:seogoogle987】,oOY
- ·https://www.lgnewsroom.com/search/谷歌maps群发程序|软件【tg:seogoogle987】,gM8
- ·https://www.resopal.de/catalogsearch/result/?action=SEARCH&q=谷歌maps群发程序|软件【tg:seogoogle987】,moY
- ·https://www.whirlpool.com.hk/chinese/catalogsearch/result?cat=30&q=谷歌maps群发程序|软件【tg:seogoogle987】,0gX
- ·https://www.normani.de/search?q=谷歌maps群发程序|软件【tg:seogoogle987】,3Sv
- ·谷歌AI搜索模式杀入西班牙语市场:全球扩张加速,直面ChatGPT竞争白热化
- ·标签: 原神 北京环球度假区 羽球节 蒙德城
- ·标签: 舍弗勒 人形机器人 具身智能 精密驱动
- ·标签: 字节 Seedance 2.0 即梦AI 豆包
- ·标签: 家居零售品牌 宜家 无印良品
- ·标签: TikTok PineDrama 微短剧 字节跳动
- ·阿里巴巴战略投资哈啰Robotaxi,自动驾驶赛道巨头联盟再添新军
- ·中国企业大模型市场爆发:半年调用量暴增363%,阿里通义居首位
- ·标签: 特斯拉 拉吉·杰加纳坦 人工智能基础设施 北美销售团队
- ·ChatGPT或将实现近百亿美元收入 未来5年收入将比早前的预测提升15%
