How to solve NodeSchool Duplexer Challange without a Duplexer package

Problem (can be downloaded from nodeschool.io/#stream-adventure )

Write a program that exports a function that starts a process from cmdand an array argsand returns a single duplex stream by combining stdin and stdout from the spawned process. There is a very convenient module that you can use here: duplexer. The duplexer module exports a single function duplexer(writable, readable)that combines the recorded stream and the read stream together into a single, read / write duplex stream.

Official decision

var spawn = require('child_process').spawn;
var duplexer = require('duplexer');

module.exports = function (cmd, args) {
    var ps = spawn(cmd, args);
    return duplexer(ps.stdin, ps.stdout);
}; 

This code basically does the following:

var spawn = require("child_process").spawn,
    Stream = require("stream");

module.exports = function (cmd, args) {
    var ps = spawn(cmd, args),
        stream = new Stream();
    stream.write = function (chunk, enc, cb) { ps.stdin.write(chunk, enc, cb); }
    stream.end = function (chunk, enc, cb) { ps.stdin.end(chunk, enc, cb); }
    ps.stdout.on("data", function (chunk) { stream.emit("data", chunk); });
    ps.stdout.on("end", function () { stream.emit("end"); });
    return stream;
}; 

Duplexer-Free Solution

I tried to solve the problem by inheriting a class Duplex:

var spawn = require("child_process").spawn,
    Stream = require("stream");

require("util").inherits(Dx, Stream.Duplex);
function Dx(stdin, stdout) {
    Stream.Duplex.call(this);
    this.stdin = stdin;
    this.stdout = stdout;
}
Dx.prototype._write = function (chunk, enc, cb) { this.stdin.write(chunk, enc, cb); };
Dx.prototype._read = function (size) { return this.stdout.read(size); };

module.exports = function (cmd, args) {
    var ps = spawn(cmd, args),
        stream = new Dx(ps.stdin, ps.stdout);
    return stream;
};

(stream-adventure verify program.js), ACTUAL vs. EXPECTED ( ), . ? .

Update

:

Dx.prototype.end = function (chunk, enc, cb) { this.stdin.end(chunk, enc, cb); }

, , , _read _write?

+4
1

process.stdin , . , process.stdin.pause(), .

.end(), , :

# 1 , , .resume() ._write():

dstream._write = function (chunk, encoding, callback) {

    this.stdin.write(chunk, encoding, callback);

    if (someConditionToEnd) {
        this.stdin.pause();
    }
};

# 2 :

/*
inside the stream prototype constructor
*/

this.on('end', function () {
    this.stdin.pause();
});
0

Source: https://habr.com/ru/post/1538727/


All Articles