ã¹ããªãŒã ã¯ã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ïŒã䜿çšããŸãã
ãŸãšãããš
ã¹ã¬ããã䜿çšãããšãã»ãšãã©ãã¹ãŠã®åé¡ã解決ã§ããŸãã
- ãã¡ã€ã«ãŸãã¯ããŒã¿ããŒã¹ãžã®ããŒã¿ã®ä¿å/èªã¿åã;
- ãã¡ã€ã«ã®ã¢ãŒã«ã€ãã
- ããŒã¿æå·å;
- ãããã¯ãŒã¯ãä»ããããŒã¿äŒéïŒãªã¢ã«ã¿ã€ã ã¡ãã»ãŒãžã³ã°ã¢ãžã¥ãŒã«ããããªããªãŒãã£ãªãã¡ã€ã«ãããŒããã£ã¹ãã®å®è£ ïŒ
圌ããèšãããã«-ãã¹ãŠã®å³ã®ããã«ã