如何解决NodeSchool的双工器的挑战,而不双工器包

问题描述 投票:4回答:1

问题(可下载从nodeschool.io/#stream-adventure

写出口会派生从cmd字符串和一个args阵列的工艺并返回单个双工流接合在一起衍生的进程的stdin和stdout的功能的程序。还有,你可以在这里使用一个非常方便的模块:双工器。双工器模块输出一个单一的功能即duplexer(writable, readable)连接在一起的可写流和可读流成一个单一的,可读/可写双工流。

官方的解决方案

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);
}; 

此代码主要执行以下操作:

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;
}; 

解决方案,而双工器包

我试图从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表(它看起来是正确的),但之后它被stucked。这有什么错我的代码?谢谢您的帮助。

更新

添加此行解决了这个问题:

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

所以,问题是,为什么没有足够的执行_read_write方法呢?

javascript node.js stream duplex
1个回答
0
投票

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();
});
© www.soinside.com 2019 - 2024. All rights reserved.