node中的流(stream)

按照官方的定義node

流(stream)是 Node.js 中處理流式數據的抽象接口。stream模塊用於構建實現了流接口的對象。

咱們通常是直接使用node提供的流對象,例如在服務器請求、文件模塊中使用。服務器

流的重要事件和方法

一、data和end事件

data事件在可讀流將數據傳給消費者後觸發,特別注意的是,添加了該事件的流會自動切換爲流動模式, end事件在當流中沒有數據可供消費時觸發:ui

const stream = fs.createReadStream('./file.txt') // 默認靜止態
let chunks = []
stream.on("data", (chunk) => { // 變成流動態
    chunks.push(chunk)
})
stream.on("end", () => {
    constcontent = Buffer.concat(chunks).toString()
    console.log(content)
})

二、readable事件與read()方法

readable事件代表流有新的動態:要麼有新的數據,要麼到達流的盡頭。下面是讀取文件的例子:code

const stream = fs.createReadStream('./file.txt')
let chunks = []
stream.on("readable", () => { // stream中無數據也會觸發readable, 此時read方法獲得null
    console.log('觸發readable');
    let data;
    while (data = stream.read(1024)) {
        chunks.push(data)
        console.log('讀取數據', data);
    }
})
stream.on("end", () => {
    const content = Buffer.concat(chunks).toString();
    console.log(content)
})

使用readable會使流的狀態變成靜止態,即便監聽了data事件。在調用read方法且有返回數據時會觸發data事件。上面代碼中,read方法讀取內部緩衝中的數據,若是不指定size參數,則是讀取內部緩衝中的全部數據,注意不是流中的全部數據,不指定size的話也就不必使用while循環了,直接一次性讀取,while循環代碼塊可變爲:server

data = stream.read()
data && chunks.push(data)
console.log('讀取數據', data);

根據運行結果,read方法將緩衝區數據讀完後會觸發readable事件,也就是當read()返回null後觸發。對象

三、pipe()

定義見官方文檔,下面例子使用pipe響應http請求接口

const http = require('http')
const fs = require('fs')
const server = http.createServer()
server.on('request', (request, response) => {
    const stream = fs.createReadStream('./file.txt')
    stream.pipe(response)
})
server.listen(8888)

數據流會被自動管理,因此即便可讀流更快,目標可寫流也不會超負荷。
上面的例子能夠用data事件改寫:事件

//....
server.on('request', (request, response) => {
    const stream = fs.createReadStream('./file.txt')
    stream.on("data", (chunk) => {
        response.write(chunk)
    })
    stream.on("end", () => {
        response.end() // 使用pipe的話默認會在可讀流觸發end事件後調用end()結束寫入
    })
})
//...

另外pipe支持鏈式操做: a.pipe(b).pipe(c) 等價於 a.pipe(b); a.pipe(c)ip

四、pause()和resume()

可讀流流動態和靜止態的切換,改變data事件是否觸發文檔

五、drain和finish事件

這兩個事件是對於可寫流的
若是可寫流調用write() 返回 false,說明寫的太快了,不能再往裏面寫了。當能夠繼續寫入數據到流時會觸發 'drain' 事件。
finish事件在調用end() 且緩衝數據都已傳給底層系統以後觸發。

六、write()和end()

上面的例子已有涉及到。write是寫入數據到可寫流,end代表寫入完畢,之久不能再調用write了

相關文章
相關標籤/搜索