zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    五秒自动刷新页面
    浅析MySQL中exists与in的使用 (写的非常好)
    基于shiro授权过程
    shiro认证
    jsp中<c:if>与<s:if>的区别
    链表数据结构相关
    队列Queue中add()和offer()的区别?
    Java中有几种线程池?
    解决idea使用jstl标签报错和不自动提示
    事务
  • 原文地址:https://www.cnblogs.com/ztwBlog/p/6257231.html
Copyright © 2011-2022 走看看