成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

注釋掉 on('data') 請求為什么一直掛著?— 了解 Node.js Stream 的兩種模式

大數據 數據分析
流剛開始處于暫停模式,所以注釋掉 req.on('data') 事件監聽,請求才會一直掛起。在基于流的方式讀取文件時,之前通常使用注冊 'data' 事件處理函數的方式從可讀流中拉取數據,現在 Node.js 支持了異步迭代,更推薦你使用 for...await of 這種方式來讀取數據,代碼看起來也會更簡潔,同步編碼思維讓人也能更好的理解。

[[414956]]

這是來自「Nodejs技術棧」交流群一位讀者朋友提的一個問題,“如果注釋掉 req.on('data') 事件監聽,end 事件就收不到了,進而永遠也不會執行 res.end(),請求會被一直掛著,為什么?”。

如果你讀到這里,也可以先思考下這個問題!

  1. const http = require('http'); 
  2. http.createServer((req, res) => { 
  3.   let data = ''
  4.  // req.on('data', chunk => { 
  5.  //  data += chunk.toString(); 
  6.  // }); 
  7.   req.on('end', () => { 
  8.     res.end(data); 
  9.   }); 
  10. }).listen(3000); 

Node.js 的可讀流對象提供了兩種模式:流動模式(flowing)、暫停模式(paused),如果你使用管道 pipe() 或異步迭代可能不會關注到這個問題,在它們的內部實現中已經處理好了,如果你是基于事件的 API 來處理流,可能會有這些疑問。

流動模式(flowing)

流動模式下數據自動從底層系統獲取,并通過 EventEmitter 提供的事件接口,盡可能快的提供給應用程序。需要注意的是所有的可讀流一開始都處于暫停模式,要切換為流動模式,可通過以下幾種方式實現:

一:注冊 'data' 事件

為可讀流對象注冊一個 'data' 事件,傳入事件處理函數,會把流切換為流動模式,在數據可用時會立即把數據塊傳送給注冊的事件處理函數。

這也是上面的疑問,為什么注釋掉 'data' 事件,請求就會一直被掛起。

  1. req.on('data', chunk => { 
  2.   data += chunk.toString(); 
  3. }); 

二:stream.pipe() 方法

調用 pipe() 方法將數據發送到可寫流。

  1. readable.pipe(writeable) 

可讀流的 pipe() 方法實現中也是注冊了 'data' 事件,一邊讀取數據一邊寫入數據至可寫流。可以參見筆者之前的這篇文章 Node.js Stream 模塊 pipe 方法使用與實現原理分析。

  1. Readable.prototype.pipe = function(dest, options) { 
  2.   const src = this; 
  3.   src.on('data', ondata); 
  4.   function ondata(chunk) { 
  5.     const ret = dest.write(chunk); 
  6.     if (ret === false) { 
  7.       ... 
  8.       src.pause(); 
  9.     } 
  10.   } 
  11.   ... 
  12. }; 

三:stream.resume() 方法

stream.resume() 將處于暫停模式的可讀流,恢復觸發 'data' 事件,切換為流動模式。

對一開始的示例做一個改造,先調用 stream.resume() 用來耗盡流中的數據,但此時沒有做任何的數據處理,之后會收到 end 事件。

  1. const http = require('http'); 
  2. http.createServer((req, res) => { 
  3.   req.resume(); 
  4.   req.on('end', () => { 
  5.     res.end('Ok!'); 
  6.   }); 
  7. }).listen(3000); 

四:異步迭代

無需注冊事件監聽函數,使用 for...await of 遍歷可讀流,寫法上也很簡單。下例,因為用到**頂級 await 特性,**需要在 ES Modules 規范中使用。

  1. // app.mjs 
  2. import { createServer as server } from 'http'
  3. import { on } from 'events'
  4. const ee = on(server().listen(3000), 'request'); 
  5. for await (const [{ url }, res] of ee) { 
  6.  res.end('OK!'); 

暫停模式

暫停模式也是流一開始時所處的模式,該模式下會觸發 'readable' 事件,表示流中有可讀取的數據,我們需要不斷調用 read() 方法拉取數據,直到返回 null,表示緩沖區中的數據已被耗盡,在 read() 返回 null 后,會再次觸發 'readable' 事件,表示仍有可讀取的數據,如果此時停止 read() 方法調用,同樣的請求也會被掛起。

stream.read(size) 方法從流緩沖區拉取數據,每次返回指定 size 大小的數據,如果不指定 size 則返回內部所有緩沖的數據。

  1. const http = require('http'); 
  2. http.createServer((req, res) => { 
  3.   let data = ''
  4.   let chunk; 
  5.   req.on('readable', () => { 
  6.     while (null !== (chunk = req.read())) { 
  7.       data += chunk.toString(); 
  8.     } 
  9.   }) 
  10.   req.on('end', () => { 
  11.     res.end(data); 
  12.   }); 
  13. }).listen(3000); 

背壓問題思考??

以流的形式從可讀流拉取數據到可寫流,通常**從磁盤讀取數據的速度比磁盤寫入的速度是快的,如果可寫流來不及消費數據造成數據積壓(專業術語會稱呼這個問題為 “背壓”)會怎么樣?**也是來自「Nodejs技術棧」交流群讀者朋友的疑問,可以思考下,答案可以寫在評論區,感興趣的關注下「Nodejs技術棧」下一次講解。

總結

 

流剛開始處于暫停模式,所以注釋掉 req.on('data') 事件監聽,請求才會一直掛起。在基于流的方式讀取文件時,之前通常使用注冊 'data' 事件處理函數的方式從可讀流中拉取數據,現在 Node.js 支持了異步迭代,更推薦你使用 for...await of 這種方式來讀取數據,代碼看起來也會更簡潔,同步編碼思維讓人也能更好的理解。

本文轉載自微信公眾號「Nodejs技術棧」,可以通過以下二維碼關注。轉載本文請聯系Nodejs技術棧公眾號。

 

責任編輯:武曉燕 來源: Nodejs技術棧
相關推薦

2015-09-15 17:01:59

2012-05-02 15:56:20

PHP

2022-03-10 07:39:33

.NET部署模式

2021-11-24 08:51:32

Node.js監聽函數

2018-03-21 18:00:15

NestJS

2020-04-15 15:48:03

Node.jsstream前端

2011-09-02 14:47:48

Node

2022-02-02 21:29:39

路由模式Vue-Router

2016-05-18 10:15:25

PythonNode.js

2010-10-20 11:06:27

公司

2017-08-17 13:56:30

JavascriptNode.jsHttp

2024-03-18 10:15:00

HTTPNode.jsAPI

2023-09-08 14:12:04

2023-10-04 07:35:03

2023-04-19 08:31:57

Node.jsLTS版本

2022-09-12 15:58:50

node.js微服務Web

2024-07-12 14:54:48

2013-12-30 09:31:34

Node.js技術

2022-01-04 21:36:33

JS瀏覽器設計

2021-07-03 08:04:10

io_uringNode.js異步IO
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美视频在线播放 | 一级黄色毛片免费 | 日韩精品在线免费 | 久久精品国产一区二区电影 | 日韩欧美成人一区二区三区 | 91欧美激情一区二区三区成人 | 91在线视频播放 | 亚洲精品亚洲人成人网 | 久久人人爽人人爽 | 国产日韩欧美一区二区 | 在线第一页 | 欧美一二三| 99精品国自产在线 | 久干网| 欧美日韩国产一区二区三区 | 国产精品久久久久久久久久99 | 在线播放国产一区二区三区 | 欧美一级免费看 | 日本精品视频一区二区三区四区 | 一区二区成人在线 | 一区二区三区av夏目彩春 | 久久精品国产一区二区 | 中文字幕一区二区三区精彩视频 | 亚洲成网| 久久久久久国产精品免费免费狐狸 | 欧美视频 亚洲视频 | 成人激情视频免费在线观看 | 久久亚洲视频网 | 少妇黄色 | 国产精品一区二区三区免费观看 | 在线亚洲免费视频 | www.av在线| 精品国产乱码久久久久久久久 | 狠狠操狠狠操 | 香蕉视频一区二区 | www.99热.com| 免费一级黄色录像 | 给我免费的视频在线观看 | 99精品99| 在线观看欧美日韩视频 | 成人午夜电影网 |