node.js Stream Buffer FsPromise
Posted Jnew
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了node.js Stream Buffer FsPromise相关的知识,希望对你有一定的参考价值。
Stream:
类似这样:a.pipe(b).pipe(c); 我想写一个b。所以:
var rs=new (require(\'stream\').Readable)(); var ws=new (require(\'stream\').Writable)(); rs._read=function(){ this.push(\'send a msn for the first time\'); this.push(\'send a msn for the second time\'); this.push(null); } ws._wirte=function(chunk,encoding,next){ console.log(chunk.toString()); next() } var Duplex=function(){ let duplex= new (require(\'stream\').Duplex)(); duplex._read=function(){ this.push(null); } duplex._write=function(chunk,e,callback){ this.push(chunk.toString()+\'...by ztw\'); next() } return duplex; } var myDuplex=Duplex(); rs.pipe(myDuplex).pipe(ws);
最后正常显示:
Buffer:
先说概念:
Unicode定义码点,utf8配置字节如何对应码点。
Buffer,你能看到是Unicode 16进制码的形式储存。
Buffer[0],这种返回的是10进制的Unicode码,这和\'string\'.charCodeAt(0)是一样的。
JS对4字节的Unicode码支持不好,\'string\'.length不对。使用:[...\'string\'].length。
var buffer=new Buffer(\'Buffer Test\',\'utf8\'); buffer.toString(\'utf8\',0,4); // \'Buff\' 位置按buffer内的位置算,非String的位置。 buffer.copy(buffer2, targetStart, sourceStart, sourceEnd) ; // 说形象点,按照[sourceStart,sourceEnd]对buffer进行裁剪,并从buffer2的targetStart位置,开始替换。 buffer.fill(\'shit\' , sourceStart, sourceEnd ); //使用shit在buffer的裁剪区域进行填充,填充方式为:repeat; buffer.fill(\'shit\') //全部填充 buffer.write(\'strawberry\', start,end); //替换某个位置。 Buffer.concat([buf1,buf2]); //合并两个Buffer;
详见官方API;
JS中有原生的buffer支持,ArrayBuffer,举个例子:
var arryBuffer=new ArrayBuffer(10); //Buffer,拥有10个字节的容量。 var arr1=new Int8Array(arryBuffer); //每个Int8Array(Unit8Array...)都带有一个ArrayBuffer。这里显示申明了而已。我们可以这样获得它: var buf=arr1.buffer; //buf指向arryBuffer,两者是一样的。 var arr2=new Int8Array(buf) ; //arr2与arr1使用同一空间,二者关联,值也相同。 var arr2=new Int8Array(buf.slice(5)); //只将5以后的空间分配给arr2,而arr1仍然全部占有。 new Buffer(buf) //可以得到这个Buffer。只能在nodeJs端使用。 buf.typeLength // 返回buf的字节容量大小。
FsPromise:
nodeJS没有提供FS的promise模块,需要自己包装:
function fsPromise(method){ return function(...args){ return new Promise((resolve,reject)=>{ method.apply(method,args.concat([(err,data)=>{resolve(data)}])) }) } }
写一个最简单直接的,其他功能可以在这基础上变通。
最后使用:
fsPromise(fs.readFile)(\'fileName\',\'utf8\').then(val=>console.log(val));
FsPromise为了跳出callBack的嵌套。还可以这样:
function thunkify(method){ return function(){ return function(...args){ return function(fn){ method(...args,fn); //相同于 method.apply(method, args.concat[fn]); }; } } }
先想定义一个thunkify;再接着写:
var readFile=thunkify(fs.readFile); var FsGen=function* (){ yield readFile(\'fileOne\',\'utf8\'); yield readFile(\'fileTwo\',\'utf8\'); } var fg=FsGen(); nextFile(); //调用nextFile,按顺序异步读取文件。 function nextFile(err,data){ let result=fg.next(); data?console.log(data):0; if(!result.done) result.value(nextFile); }
同样跳出callback嵌套。而generators 配合thunkify函数,可以异步处理更多的文件。
使用thunkify,为了让readFile再返回一个function,并在其中执行fg.next()。如果在readFile中执行fg.next()。会返回Generators is aready running;
--------------------------来一个FsPromise的实例-----------------------------:
function toPromise(method){ return function(){ return functin(...args){ return new Promise((resolve,reject)=>{ method(...args,(...data)=>{ resolve(data); //把它小小升级一下,data为array型,以支持不同参型。 }) }) } } } process.stdin.setEncoding(\'utf8\'); const stdinOnce=process.stdin.once.bind(process.stdin);//记得bind; toPromise(stdinOnce)(\'data\').then(val=>{ process.stdout.write(...val); console.log(\'step1\'); return toPromise(stdinOnce)(\'data\'); }) .then(val=>{ process.stdout.write(...val); console.log(\'step2\'); return toPromise(stdinOnce)(\'data\'); }) .then(val=>{ console.log(\'end\'); process.stdout.end(); })
实现一个,按步骤根据用户输入就来进行回应的,大致框架。
因为fs.readFile本身是一个obj,所以可以直接toPromise(fs.readFile)。
而process.stdin.one是一个方法,直接另名为stdinOnce,会丢失内部的this。
而使用method.call(process.stdin),也不可取。
所以:
const stdinOnce=process.stdin.once.bind(process.stdin);
以上是关于node.js Stream Buffer FsPromise的主要内容,如果未能解决你的问题,请参考以下文章
Node.js实战对于Buffer和Stream模块系统的深入剖析
Node.js之文件及文件流(fs,path,buffer,stream)
Node.js学习08:思考Buffer 类型产生的原因?主要用来解决什么问题?