Node中的streams流的具體使用
Node中的streams流
streams流是Node中的最好的特性之一。它在我們的開發(fā)過程當(dāng)中可以幫助我們做很多事情。比如通過流的方式梳理大量數(shù)據(jù),或者幫我們分離應(yīng)用程序。
和streams流相關(guān)的內(nèi)容有哪些呢?大致有這么幾點(diǎn):
- 處理大量數(shù)據(jù)
- 使用管道方法
- 轉(zhuǎn)換流
- 讀寫流
- 解耦I(lǐng)/O
轉(zhuǎn)換流
Node中的流其實(shí)是允許我們進(jìn)行異步編程的。最常見的就是轉(zhuǎn)換流,它就像是一個(gè)接收輸入并且產(chǎn)生輸出的大黑盒子。
舉個(gè)例子:
const through = require('through2') const upper = through((chunk, enc, cb) => { cb(null, chunk.toString().toUpperCase()) }) process.stdin.pipe(upper).pipe(process.stdout)
執(zhí)行它,我們在終端輸入的內(nèi)容,它會轉(zhuǎn)換成大寫并且重新輸出到終端。
through2模塊在核心流的構(gòu)造器上又加了一層。當(dāng)我們創(chuàng)建upper時(shí),我們給through傳了一個(gè)回調(diào)函數(shù)進(jìn)去,這個(gè)回調(diào)函數(shù)就是轉(zhuǎn)換方法。流中的每段數(shù)據(jù)都將通過這個(gè)方法,chunk表示數(shù)據(jù),enc表示數(shù)據(jù)的編碼格式,cb是一個(gè)回調(diào)函數(shù),我們執(zhí)行它表示我們已經(jīng)完成了數(shù)據(jù)處理,并且進(jìn)行下一步處理。
使用through2模塊進(jìn)行處理數(shù)據(jù),一方面可讀性更強(qiáng),另一方面,可以保持Node版本之前的行為一致。
創(chuàng)建
大多數(shù)情況下,當(dāng)我們使用核心模塊時(shí),我們會直接使用。例如:
const fs = require('fs') const stream = require('stream')
但是經(jīng)驗(yàn)告訴我們:不要直接使用核心流模塊。我們可以使用readable-stream,雖然名字不一樣,但是這確實(shí)可以保證我們在不同的Node版本之間保持很好的一致性。所以在代碼中我們應(yīng)該盡可能的使用readable-stream
const stream = require('readable-stream')
看這個(gè)例子:
const stream = require('readable-stream') const util = require('util') function MyTransform(opts){ stream.Transform.call(this,opts) } util.inherits(MyTransform,stream.Transform) MyTransform.prototype._transform = function(chunk,enc,cb){ cb(null,chunk.toString().toUpperCase()) } const upper = new MyTransform() process.stdin.pipe(upper).pipe(process.stdout)
在Node的早期版本中,這是創(chuàng)建流的標(biāo)準(zhǔn)方式。但是es6出現(xiàn)以后,有一種更簡單的方法。
const {Transform} = require('readable-stream') class MyTransform extends Transform { _transform(chunk,enc,cb){ cb(null,chunk.toString().toUpperCase(),) } } const upper = new MyTransform() process.stdin.pipe(upper).pipe(process.stdout)
對象模式
如果我們的流不是返回的序列換的數(shù)據(jù),一般是buffer或者string,我們需要將它轉(zhuǎn)換成一個(gè)對象。但是我們需要知道具體傳了多少數(shù)據(jù)過來。
默認(rèn)情況下,當(dāng)不使用對象模式時(shí),流將在暫停前緩沖大約16KB的數(shù)據(jù)。使用對象模式時(shí),當(dāng)緩沖了16個(gè)對象后,它將開始暫停。
再來看一個(gè)例子:
const through = require('through2') const ndjson = require('ndjson') const xyz = through.obj(({ x, y }, enc, cb) => { cb(null, { z: x + y }) }) xyz.pipe(ndjson.stringify()).pipe(process.stdout) xyz.write({ x: 199, y: 3 }) xyz.write({ x: 10, y: 12 })
這個(gè)例子會打印下面的結(jié)果
我們用through2模塊的obj方法創(chuàng)建了一個(gè)流。然后通過pipe方法write的信息進(jìn)行stringify然后再傳給process.stdout,最后返回了計(jì)算后的結(jié)果。
我們也可以使用readable-stream模塊來實(shí)現(xiàn)這個(gè):
const {Transform} = require('readable-stream') const {serialize} = require('ndjson') const xyz = Transform({ objMode:true, transform:({x,y},enc,cb)=>{ cb(null,{z:x+y}) } }) xyz.pipe(ndjson.stringify()).pipe(process.stdout) xyz.write({ x: 199, y: 3 }) xyz.write({ x: 10, y: 12 })
同樣可以實(shí)現(xiàn)上面的效果。
最后
到此這篇關(guān)于Node中的streams流的具體使用的文章就介紹到這了,更多相關(guān)Node streams流內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Node.js中使用Log.io在瀏覽器中實(shí)時(shí)監(jiān)控日志(等同tail -f命令)
這篇文章主要介紹了Node.js中使用Log.io在瀏覽器中實(shí)時(shí)監(jiān)控日志,Log.io等同于tail -f命令,但更強(qiáng)大,需要的朋友可以參考下2014-09-09整理 node-sass 安裝失敗的原因及解決辦法(小結(jié))
這篇文章主要介紹了整理 node-sass 安裝失敗的原因及解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Egret引擎開發(fā)指南之運(yùn)行項(xiàng)目
Egret Framework是一款使用TypeScript語言構(gòu)建的開源免費(fèi)的移動(dòng)游戲框架。Egret Framework的核心定位是開放,高效,優(yōu)雅。通過它,你可以快速地創(chuàng)建HTML5類型的移動(dòng)游戲,也可以將游戲項(xiàng)目編譯輸出成為目標(biāo)移動(dòng)平臺的原生游戲應(yīng)用。2014-09-09基于promise.js實(shí)現(xiàn)nodejs的promises庫
promise是JavaScript實(shí)現(xiàn)優(yōu)雅編程的一個(gè)非常不錯(cuò)的輕量級框架。該框架可以讓你從雜亂的多重異步回調(diào)代碼中解脫出來,并把精力集中到你的業(yè)務(wù)邏輯上。2014-07-07Nodejs實(shí)現(xiàn)獲取實(shí)時(shí)數(shù)據(jù)的三種主流方式詳解
這篇文章主要為大家詳細(xì)介紹了Nodejs前端獲取實(shí)時(shí)數(shù)據(jù)的三種主流方式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02