ã¹ããªãŒã ã¯ãI / Oæäœã§1ã€ã®ããã°ã©ã ããå¥ã®ããã°ã©ã ã«ããŒã¿ã転éããããã«UNIXã·ã¹ãã ã«æåã«å®è£ ãããæŠå¿µã§ãã ããã«ãããåããã°ã©ã ã¯ãããè¡ãããšã§éåžžã«ç¹æ®åãããç¬ç«ããã¢ãžã¥ãŒã«ã«ãªããŸãã ãã®ãããªåçŽãªããã°ã©ã ã®çµã¿åããã¯ãäžé£ã®åŒã³åºãã«ãçµã¿åããããŠãããè€éãªã·ã¹ãã ãäœæããã®ã«åœ¹ç«ã¡ãŸãã
ã¹ããªãŒã ã䜿çšãããšãå°ããªéšåã§ããŒã¿ã亀æã§ãããããäœæ¥äžã«å€§éã®ã¡ã¢ãªãæ¶è²»ããããšããªããªããŸãã ãã¡ãããããã¯å éšãããŒæ©èœã®å®è£ æ¹æ³ã«äŸåããŸãã
äžè¬çãªã¿ã¹ã¯ã¯ã倧ããªãã¡ã€ã«ãè§£æããããšã§ãã ããšãã°ããã°ããŒã¿ãå«ãããã¹ããã¡ã€ã«ã§ã¯ãç¹å®ã®ããã¹ããå«ãè¡ãèŠã€ããå¿ èŠããããŸãã ãã¡ã€ã«ãã¡ã¢ãªã«å®å šã«èªã¿èŸŒãã§ãããå¿ èŠãªè¡ãæ¢ããŠãã®è¡ãè§£æãå§ãã代ããã«ãå°ããã€èªãããšãã§ããŸãã ãããã£ãŠãå¿ èŠä»¥äžã®ã¡ã¢ãªãå æããã®ã§ã¯ãªããèªã¿åãããŒã¿ããããã¡ãªã³ã°ããããã«å¿ èŠãªã ãã®ã¡ã¢ãªãå æããŸãã å¿ èŠãªã¬ã³ãŒããèŠã€ãã£ãããããã«ãã以äžã®äœæ¥ã忢ããŸãã ãŸãã¯ãèŠã€ãã£ãã¬ã³ãŒãããã§ãŒã³å ã®å¥ã®ã¹ããªãŒã ã«è»¢éããŠãããšãã°å¥ã®åœ¢åŒã«å€æããããå¥ã®ãã¡ã€ã«ã«ä¿åãããã§ããŸãã
ã¹ããªãŒã ã¢ãžã¥ãŒã«ã¯ãNode.JSã§ã¹ããªãŒã ãæäœããããã®åºæ¬çãªAPIãæäŸããŸãã Node.JSã®ããã¥ã¡ã³ãã¯ãã®åé¡ãçè§£ããã®ã«ååã§ãããããã€ãã®ãã€ã³ãã®èª¬æãå«ãããŒãã·ãŒãã®ãããªãã®ãäœæããããšããŸãã
ã¹ããªãŒã ã®çš®é¡
ã¹ã¬ããã«ã¯4ã€ã®ã¿ã€ãããããŸãã
- èªã¿åãå¯èœ-èªã¿åãçšã®ããŒã¿ãæäŸããã¹ããªãŒã ã
 - æžã蟌ã¿å¯èœ-ããŒã¿ãæžã蟌ãããšãã§ããã¹ããªãŒã ã
 - äºé-ããŒã¿ã®èªã¿åãïŒèªã¿åãå¯èœïŒãšæžã蟌ã¿ïŒæžã蟌ã¿å¯èœïŒã®äž¡æ¹ãå¯èœãªã¹ããªãŒã ãèªã¿åããšæžã蟌ã¿ã®ããã»ã¹ã¯äºãã«ç¬ç«ããŠè¡ãããŸãã
 - 倿ã¯ãã¹ããªãŒã ã«ããŒã¿ãæžã蟌ãã ãã¹ããªãŒã ããããŒã¿ãèªã¿èŸŒãã ããããšãã«ããŒã¿ã倿Žã§ãããã¥ãã¬ãã¯ã¹ã¹ããªãŒã ã®äžçš®ã§ãïŒããŒã¿è»¢éãã§ãŒã³ã®äžéãªã³ã¯ãšããŠãã䜿çšãããŸãïŒã
 
EventEmitterã®ã¹ããªãŒã ã€ã³ã¹ã¿ã³ã¹
ãã¹ãŠã®ã¹ããªãŒã ã¯EventEmitterã®ã€ã³ã¹ã¿ã³ã¹ã§ããã€ãŸããStreamClass.emitïŒ 'eventName'ãdataïŒã€ãã³ããçæããããããåŠçã§ããŸãStreamClass.onïŒ 'eventName'ãïŒdataïŒ=> {}ïŒ;
ãã€ãæ¹åŒ
ããã¹ã¬ããããå¥ã®ã¹ã¬ããã«ããŒã¿ã転éããã«ã¯ãã¹ã¬ããã§ãã€ãã¡ãœãããåŒã³åºãæãç°¡åãªæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
Readable.pipe(Writable);//,  "" DataBase -> File Readable.pipe(Transform).pipe(Writable);//DataBase ->   JSON  ->  JSON  File Duplex.pipe(Transform).pipe(Duplex);//  DataBase ->  ->    DataBase 
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      åŒã³åºãã®æåŸã®ãã§ãŒã³ã¯ããããããç¬èªã®åé¡ã解決ãããããªæ¹æ³ã§ã¹ããªãŒã ã¯ã©ã¹ãå®è£ ããæ¹ãè¯ãããšã瀺ããŠããŸãã
ã芧ã®ãšãããpipeã¡ãœããã¯ãæž¡ãããã¹ããªãŒã ã®ã€ã³ã¹ã¿ã³ã¹ãè¿ããŸããããã«ãããã¹ã¬ãããçµåã§ããŸãã
ãã€ãã¡ãœããã¯ã1ã€ã®ã¹ããªãŒã ããå¥ã®ã¹ããªãŒã ãžã®ããŒã¿è»¢éã®ãé床ããå¶åŸ¡ããåé¡ã解決ããããã«å®è£ ãããŸãïŒå éšã¹ããªãŒã ãããã¡ãŒã®ããªã¥ãŒã ãè¶ ããïŒã ããšãã°ãWritableã¹ããªãŒã ã¯ãReadableããŒã¿ãœãŒã¹ãæž¡ããããé ãéåºŠã§æžã蟌ã¿ãŸãã ãã®å ŽåãããŒã¿ã®æ¬¡ã®éšåãåä¿¡ããæºåãã§ããããšãæžã蟌ã¿å¯èœããéç¥ãããïŒå éšãããã¡ãã¯ãªã¢ãããïŒãŸã§ãããŒã¿è»¢éã¯ãäžæããããŸãã
ãããã¡ãªã³ã°
ã¹ããªãŒã ã¯ãå éšãããã¡ãŒã«ããŒã¿ãä¿åããŸãã ãããã¡ãŒãµã€ãºã¯ãã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ãŒã§èšå®ã§ããhighWaterMarkãã©ã¡ãŒã¿ãŒã䜿çšããŠæå®ã§ããŸãã
highWaterMarkã®ç©ççãªæå³ã¯ãå¥ã®ãªãã·ã§ã³-objectModeã«äŸåããŸãã
 new StreamObject({objectMode: false, highWaterMark: __}); //  16384 (16kb) new StreamObject({objectMode: true, highWaterMark: __});//  16
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      Readableã¹ããªãŒã ã§ã¯ãããŒã¿ã¯pushïŒdataïŒã¡ãœãããåŒã³åºããããšãããã¡ãªã³ã°ãããreadïŒïŒã¡ãœãããåŒã³åºããŠèªã¿åããããŸã§ãããã¡å ã«æ®ããŸãã èªã¿åãå¯èœãªã¹ããªãŒã ã®å éšãããã¡ãŒã®åèšãµã€ãºãhighWaterMarkã§æå®ããããããå€ã«éãããšãã¹ããªãŒã ã¯ããŒã¿ã®èªã¿åããäžæçã«åæ¢ããŸãã
æžã蟌ã¿å¯èœã®å Žåãæžã蟌ã¿ïŒããŒã¿ïŒã¡ãœãããåŒã³åºããããšãããã¡ãªã³ã°ãçºçããŸãã ãã®ã¡ãœããã¯ããããã¡ãŒãµã€ãºãhighWaterMarkã«éãããŸã§trueãè¿ãããããã¡ãŒããã£ã±ãã«ãªããšfalseãè¿ããŸãã
pipeïŒïŒã¡ãœããã䜿çšããå Žåããã®ç¬éã«ããŒã¿ã®èªã¿åããã忢ãããããã¬ã€ã³ãã€ãã³ããåŸ æ©ããŸãããã®åŸãããŒã¿è»¢éãåéãããŸãã
ãªããžã§ã¯ãã¢ãŒã
ããã©ã«ãã§ã¯ãã¹ããªãŒã ã¯ãããã¡åœ¢åŒã®ããŒã¿ãåŠçããŸãããæååãšä»ã®JavaScriptãªããžã§ã¯ãã®äž¡æ¹ãåŠçããããšãã§ããŸãïŒããšãã°ã{"user"ïŒ{"name"ïŒ "Ivan"ã "last_name"ïŒ "Petrov" }}ïŒãããŒã¿ã®éä¿¡ã§å¥ã®åœ¹å²ãæããnullãªããžã§ã¯ããé€ããŸãïŒã¹ããªãŒã ãnullãåä¿¡ããå Žåãããã¯åŠçããããŒã¿ããªããããŒã¿ã®èªã¿åããŸãã¯æžã蟌ã¿ãå®äºããããšã瀺ãä¿¡å·ã§ãïŒã åæåäžã«ã¹ããªãŒã ã®ç¹å®ã®ã¢ãŒããèšå®ããæ¹æ³ã¯ã以äžã®äŸã«ç€ºãããŠããŸãã
ã¹ããªãŒã ã®èªã¿åãå¯èœãŸãã¯äžæåæ¢ç¶æ 
- ãããŒ-ããŒã¿ã¯ãããããèªã¿åãããã»ã¹ã®ããã«ãç¶ç¶çãã€å¯èœãªéãè¿ éã«åä¿¡ãããŸãã
 - äžæåæ¢-ãã¹ãŠã®ã¿ã€ãã®ã¹ããªãŒã ã®ããã©ã«ãã¢ãŒããããŒã¿ã¯æç€ºçã«èŠæ±ãããå Žåã«ã®ã¿éä¿¡ãããŸã-readïŒïŒã¡ãœããã®æç€ºçãªåŒã³åºãïŒreadïŒïŒã¡ãœããã¯æé»çã«pipeïŒïŒã¡ãœããã®ãå éšããšåŒã°ããŸãïŒ
 
ç¶æ ãããŒ=== true-次ã®å Žåã«èªåçã«ïŒ
- ããŒã¿ã¯pipeïŒïŒã¡ãœãããä»ããŠä»ã®ã¹ã¬ããã«æž¡ãããŸãã
 - ããã³/ãŸãã¯ã€ãã³ããã³ãã©ãããŒã¿ããæã£ãŠããŸã;
 - ããã³/ãŸãã¯ãã®äžã§resumeïŒïŒã¡ãœãããåŒã³åºãããŸãã
 
ãããŒç¶æ ããäžæåæ¢ç¶æ ã«åãæ¿ããããšãã§ããŸãïŒãããŒ=== falseïŒïŒ
- ããŒã¿ãœãŒã¹ãšãã®ã³ã³ã·ã¥ãŒããŒã®éã®æ¥ç¶ããåæãããå ŽåïŒReadable.pipeïŒWritableïŒ; ReadableãunpipeïŒWritableïŒïŒãããã³/ãŸãã¯ã€ãã³ããã³ãã©ãŒ 'data'ãåé€ããŸãã
 - ãŸãã¯Readable.pauseïŒïŒã¡ãœãããåŒã³åºããŸãã
 
Readable flow === nullã¯ã©ã¹ã®åæåæãã€ãŸããããŒã¿èªã¿åãã¡ã«ããºã ã¯ãŸã å®è£ ãããŠããããããŒã¿ã¯çæãããŸããã
èªã¿åãå¯èœãªã¹ããªãŒã -ããŒã¿ãœãŒã¹ãšããŠã®ã¹ããªãŒã
      èªã¿åãå¯èœãªã¹ã¬ããã¯ããããŒãšäžæåæ¢ã®2ã€ã®ç¶æ ã®ããããã§åäœããŸãã äžæåæ¢ç¶æ ã§ããŒã¿ãèªã¿åãã«ã¯ãæç€ºçã«readïŒïŒã¡ãœãããåŒã³åºãå¿ èŠããããŸãã ããã¹ããªãŒã ããå¥ã®ã¹ããªãŒã ã«ããŒã¿ã転éãããšïŒR.pipeïŒWïŒïŒãreadïŒïŒã¡ãœãããèªåçã«åŒã³åºãããŸãã
Readable._readableState.bufferããããã£ã䜿çšããŠãçŸåšã®ããŒã¿ãããã¡ãŒå šäœãååŸã§ããŸãã
  Readable.jsã®äŸ 
        
        
        
      
    
       'use strict'; const { Readable } = require('stream'); /** *     Readable ,    _read(). *       *    (_readableState)   ,      (on('end', ()=>{})) */ class Source extends Readable { constructor(array_of_data = [], opt = {}) { super(opt); this._array_of_data = array_of_data; console.log('objectMode ', this._readableState.objectMode);//false  ,      console.log('highWaterMark ', this._readableState.highWaterMark);//16384 console.log('buffer ', this._readableState.buffer);//[] -   console.log('length ', this._readableState.length);//0 - -   console.log('flowing ', this._readableState.flowing);//null //  ,      this.on('data', (chunk)=> { //   'data' -         console.log('\n---'); console.log('Readable on data '); // chunk     console.log(`chunk = ${chunk} chunk isBuffer ${Buffer.isBuffer(chunk)} and chunk.length is ${chunk.length}`); //-     (-  ) console.log('buffer.length ', this._readableState.buffer.length); console.log(': ', chunk.toString(), ' buffer of chunk ', this._readableState.buffer, ' buffer of chunk   ', this._readableState.buffer.toString()); }) .on('error',(err)=> { console.log('Readable on error ', err); }) .on('end',()=> { console.log('Readable on end '); console.log('objectMode ', this._readableState.objectMode);//false console.log('highWaterMark ', this._readableState.highWaterMark);//16384 console.log('buffer ', this._readableState.buffer);//[] -   console.log('buffer.length ', this._readableState.buffer.length);//0 console.log('flowing ', this._readableState.flowing);//true !!!       'data' }) .on('close',()=> { console.log('Readable on close      '); }); } _read() { let data = this._array_of_data.shift() if (!data) { //,    this.push(null); } else { this.push(data); } } } /*   , ..       ,   .         this.push(data) Readable on error TypeError: Invalid non-string/buffer chunk */ let array_of_data = ['1', '2', '3', '4', '5']; let opts = {/*     */}; const R = new Source(array_of_data, opts); array_of_data = ['1', '2', '3', '4', '5']; opts = { objectMode: false, highWaterMark: 1//1      _readableState.buffer.length  === 1 }; const R2 = new Source(array_of_data, opts); array_of_data = ['1', '2', '3', '4', '5']; opts = { objectMode: false , encoding: 'utf8'//   ( NodeJS),         ,      }; const R3 = new Source(array_of_data, opts);//        .setEncoding('utf8') array_of_data = [1, 2, 3, 4, 5]; /*  ""   .  objectMode: true      -   ,    Readable.setEncoding('utf8')*/ opts = { objectMode: true , encoding: 'utf8' }; const R4 = new Source(array_of_data, opts); // objectMode: true    ,    (Number) array_of_data = [1, 2, 3, 4, 5]; opts = { objectMode: true }; const R5 = new Source(array_of_data, opts); //highWaterMark 16 -      /*     (    Writable.write(someData) === false).      Node.JS.  ,      ,    ,    */ array_of_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; opts = { objectMode: true }; const R6 = new Source(array_of_data, opts); R6.on('data', (chunk) => { //    1  R6.pause(); setTimeout(() => { R6.resume();//   }, 1000); });
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      æžã蟌ã¿å¯èœãªã¹ããªãŒã -ããŒã¿ãæžã蟌ãããã®ã¹ããªãŒã
      çŸåšã®ããŒã¿ãããã¡å šäœã¯ãwritable._writableState.getBufferïŒïŒã¡ãœããã䜿çšããŠååŸã§ããŸãã
  Writable.jsã®äŸ 
        
        
        
      
    
       'use strict'; const Source = require('./readable.js'); const { Writable } = require('stream'); class Writer extends Writable { constructor(opt = {}) { super(opt); console.log('objectMode ', this._writableState.objectMode);//false  ,     true console.log('highWaterMark ', this._writableState.highWaterMark);//16384 console.log('decodeStrings ', this._writableState.decodeStrings);//true  ;    Buffer ,      _write() console.log('buffer ', this._writableState.getBuffer());//[] -   this.on('drain', ()=> { console.log('\n------ writable on drain'); }) .on('error', (err)=> { console.log('\n------ writable on error', err); }) .on('finish', ()=> { console.log('\n------ writable on finish'); console.log('_writableState.getBuffer()', this._writableState.getBuffer()); }); } /** * @param chunk - || * @param encoding -   .  objectMode === true,  encoding   * @param done - callback -.     ,     ,    *   _write,  ,       chunk,      *  : done(err) -     new Error(...) * @private */ _write(chunk, encoding, done) { console.log('_writableState.getBuffer()', this._writableState.getBuffer()); console.log(typeof chunk ); //    Transform   if (typeof chunk === 'object') { console.log('chunk = ', chunk.get(), chunk.get() +' in pow '+ chunk.get() +' = '+ chunk.inPow(chunk.get())); } else { console.log(`chunk = ${chunk}; isBuffer ${Buffer.isBuffer(chunk)}; chunk.length is ${chunk.length}; encoding = ${encoding}`); } /*     . , : 1)     on('error', (err)=>{...}) 2)   ,    Readable    .         - ,  Readable.emit('error', err);     Readable.puse(),      Readable.remuse().    ,           //if (chunk > 3) return done(new Error('chunk > 3'));*/ done(); } } let array_of_data = ['1', '2', '3', '4', '5']; let r_opts = {/*    */}; const R = new Source(array_of_data, r_opts); let w_opts = {/*    */}; const W = new Writer(w_opts); R.pipe(W); array_of_data = ['1', '2', '3', '4', '5']; r_opts = {encoding: 'utf8'}; const R1 = new Source(array_of_data, r_opts); w_opts = { decodeStrings: false//  _write     'utf8',      -  (  r_opts), }; const W1 = new Writer(w_opts); R1.pipe(W1); array_of_data = [1, 2, 3, 4, 5]; r_opts = {objectMode: true}; const R2 = new Source(array_of_data, r_opts); w_opts = { objectMode: true// false,       ( r_opts),   "TypeError: Invalid non-string/buffer chunk" }; const W2 = new Writer(w_opts); R2.pipe(W2); array_of_data = [1, 2, 3, 4, 5]; r_opts = {objectMode: true}; const R3 = new Source(array_of_data, r_opts); w_opts = { objectMode: true// false,       ( r_opts),   "TypeError: Invalid non-string/buffer chunk" , highWaterMark: 1 // ;          'drain' }; const W3 = new Writer(w_opts); R3.pipe(W3); //  pipe() const R3_1 = new Source(array_of_data, r_opts); const W3_1 = new Writer(w_opts); R3_1.on('data', (chunk)=> { //R3_1._readableState.flowing === true console.log('R3_1 in flowing mode', R3_1._readableState.flowing, 'R3_1 _readableState.buffer', R3_1._readableState.buffer); toWriteOrNotToWriteThatIsTheQuestion(chunk, onDrain); }); function onDrain() { //R3_1._readableState.flowing === false,      R3_1.pause()  toWriteOrNotToWriteThatIsTheQuestion console.log('R3_1 in flowing mode', R3_1._readableState.flowing); R3_1.resume(); } /** *           Writable,       Readable (R3_1.pause()) *     ( 'drain'),       Readable ( cb R3_1.resume(); ),    Writable * @param data * @param cb */ function toWriteOrNotToWriteThatIsTheQuestion(data, cb) { // " "     write(...),    _write(...) if (!W3_1.write(data)) { R3_1.pause(); W3_1.once('drain', cb); } else { process.nextTick(cb); } }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      ã¹ããªãŒã ã®å€æ-ããŒã¿å€æŽã¹ããªãŒã
      倿ã¯ããã¥ãã¬ãã¯ã¹ã¹ããªãŒã ã®ããªãšãŒã·ã§ã³ã§ãã ç§ãã¡ã¯åœŒãšæåã«äŸãèšå®ããããšã«ããŸããã
  Transform.jsã®äŸ 
        
        
        
      
    
       'use strict'; const Readable = require('./readable.js'); const Writable = require('./writable.js'); const {Transform} = require('stream'); /*  ,      , ,  JS ,    */ class Chunk { constructor(chunk) { this.set(chunk); } set(chunk) { this._chunk = chunk; } get() { return this._chunk; } inPow(pow = 2) { return Math.pow(this.get(), pow); } } class Transformer extends Transform { constructor(opt = {}) { super(opt); console.log('\n -------- Transform in constructor'); console.log('objectMode ', this._writableState.objectMode);//false  ,     true console.log('highWaterMark ', this._writableState.highWaterMark);//16384 console.log('decodeStrings ', this._writableState.decodeStrings);//true  ;    Buffer ,      _write() console.log('buffer ', this._writableState.getBuffer());//[] -   this.on('close', ()=> { console.log('\n------ Transform on close'); }) .on('drain', ()=> { console.log('\n------ Transform on drain'); }) .on('error', (err)=> { console.log('\n------ Transform on error', err); }) .on('finish', ()=> { console.log('\n------ Transform on finish'); }) .on('end', ()=> { console.log('\n------ Transform on end'); }) .on('pipe', ()=> { console.log('\n------ Transform on pipe'); }); } /** * ,      (chunk    Transform), *    -      Transform * @param chunk * @param encoding * @param done -    done(err, chunk) * @private */ _transform(chunk, encoding, done) { /*    chunk,         done(null, chunk); done(err, chunk); -       error  ,    : this.push(chunk); done(); this.push(chunk); done(err);*/ //      Chunk (.  writable.js) this.push(new Chunk(chunk)); done(); } /** *  transform     _flush.   ,      ,    'end'  Readable (  Transform,       ,    ). * @param done - done(err)     Error * @private */ _flush(done) { //TODO ... -       done(); } } let array_of_data = ['1', '2', '3', '4', '5']; let r_opts = { encoding: 'utf8' }; const R = new Readable(array_of_data, r_opts); let t_opts = { readableObjectMode: true //   Transform   , writableObjectMode: false//   Transform      , decodeStrings: false }; const T = new Transformer(t_opts); let w_opts = { objectMode: true// false,    }; const W = new Writable(w_opts); R.pipe(T).pipe(W);
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      ãã¥ãã¬ãã¯ã¹ã¹ããªãŒã -ã¹ããªãŒã ã®æžã蟌ã¿ãšèªã¿åã
ãã¥ãã¬ãã¯ã¹ã¯ãèªã¿åãå¯èœãæžã蟌ã¿å¯èœãªã¹ããªãŒã ãšããŠããèªäœãå®è£ ããŸãã ããã«ããããã®ãäœæ¥ãã¯äºãã«ç¬ç«ããŠçºçããŸãã
ã¹ããªãŒã ã®ãããã¯ã«èå³ãããå Žåã¯ãDuplexã¹ããªãŒã ã®å®è£ ãèªåã§è©ŠããŠã¿ãããšããå§ãããŸãã
  æ°ããstream.DuplexïŒãªãã·ã§ã³ïŒ 
       æ°ããstream.DuplexïŒãªãã·ã§ã³ïŒ 
      
        
        
        
      
optionsãªããžã§ã¯ãã¯ãDuplexã¹ããªãŒã ã®Writableããã³Readableã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ãããŸãã
        
        
        
      
    
      
        
        
        
      
    
        
        
        
      
    
optionsãªããžã§ã¯ãã¯ãDuplexã¹ããªãŒã ã®Writableããã³Readableã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ãããŸãã
- allowHalfOpenããŒã«å€ã¯ããã©ã«ãã§trueã§ãã falseã®å Žåãèªã¿åãã¹ããªãŒã ãåŠçãå®äºãããšãèªåçã«çµäºããæžã蟌ã¿ã¹ããªãŒã ãçµäºããŸãã
 - readableObjectModeããŒã«å€ã¯ããã©ã«ãã§falseã§ãã èªã¿åãå¯èœãªã¹ããªãŒã ã®objectModeã¢ãŒãã ããããã£objectMode = trueã®å Žåãããããã£ã®å€ã¯ç¡èŠãããŸãã
 - writableObjectMode booleanã¯ããã©ã«ãã§falseã§ãã æžã蟌ã¿å¯èœãªã¹ããªãŒã ã®objectModeã¢ãŒãã ããããã£objectMode = trueã®å Žåãããããã£ã®å€ã¯ç¡èŠãããŸãã
 
ãšã©ãŒåŠç
äžéšã®ãªã³ã¯ã§ããšã©ãŒãã€ãã³ããããªã¬ãŒããããã§ãŒã³å ã®ãåã®ãã¹ããªãŒã ã«éç¥ããå¿ èŠãããå Žåãããšã©ãŒãã€ãã³ããåŒã³åºãå¿ èŠããããŸãïŒStreamClass.emitïŒ 'error'ãerrïŒç¶æ³ãåŠçããŸãã ãŸãã¯ããã®åé¡ã解決ã§ãããã³ãã¢ãžã¥ãŒã«ïŒhttps://github.com/mafintosh/pumpïŒã䜿çšããŸãã
ãŸãšãããš
ã¹ã¬ããã䜿çšãããšãã»ãšãã©ãã¹ãŠã®åé¡ã解決ã§ããŸãã
- ãã¡ã€ã«ãŸãã¯ããŒã¿ããŒã¹ãžã®ããŒã¿ã®ä¿å/èªã¿åã;
 - ãã¡ã€ã«ã®ã¢ãŒã«ã€ãã
 - ããŒã¿æå·å;
 - ãããã¯ãŒã¯ãä»ããããŒã¿äŒéïŒãªã¢ã«ã¿ã€ã ã¡ãã»ãŒãžã³ã°ã¢ãžã¥ãŒã«ããããªããªãŒãã£ãªãã¡ã€ã«ãããŒããã£ã¹ãã®å®è£ ïŒ
 
圌ããèšãããã«-ãã¹ãŠã®å³ã®ããã«ã