使用stream-combiner和Writable Streams(stream-adventure)

时间:2016-11-19 11:37:17

标签: node.js

我正在开发nodeschool.io的流冒险。挑战:

编写一个使用。返回可读/可写流的模块 stream-combiner模块。您可以使用此代码开头:

var combine = require('stream-combiner')
module.exports = function () {
    return combine(
        // read newline-separated json,
        // group books into genres,
        // then gzip the output
    )
}

您的信息流将编写一个以换行符分隔的JSON科幻小说列表 流派和书籍。 "type":"genre"行之后的所有书籍都属于该行 直到下一个"type":"genre"出现在输出中。

{"type":"genre","name":"cyberpunk"}
{"type":"book","name":"Neuromancer"}
{"type":"book","name":"Snow Crash"}
{"type":"genre","name":"space opera"}
{"type":"book","name":"A Deepness in the Sky"}
{"type":"book","name":"Void"}

你的程序应该生成一个以换行符分隔的JSON行类型列表, 每个都有一个"books"数组,其中包含该类型的所有书籍。输入 以上将产生输出:

{"name":"cyberpunk","books":["Neuromancer","Snow Crash"]}
{"name":"space opera","books":["A Deepness in the Sky","Void"]}

您的流应该使用此JSON行列表并使用它进行gzip zlib.createGzip()

HINTS

stream-combiner模块从流列表中创建管道, 返回单个流,将第一个流公开为可写侧 最后一个流作为可读方,如duplexer模块,但有一个 中间任意数量的流。与duplexer模块不同 流被传送到下一个。例如:

var combine = require('stream-combiner');
var stream = combine(a, b, c, d);

将在内部执行a.pipe(b).pipe(c).pipe(d)stream返回 combine()将其可写端连接到a并且其可读侧被钩住 进入d

与之前的LINES冒险一样,split模块在​​这里非常方便。您 可以将拆分流直接放入流组合器管道中。 请注意,拆分也可以发送空行。

如果您最终使用splitstream-combiner,请确保安装它们 进入解决方案文件所在的目录:

`npm install stream-combiner split`

注意:当您测试程序时,源流会自动插入到程序中,因此将split()作为combine(split(), etc., etc.)

中的第一个参数完全正常

我正试图在不使用'through'包的情况下解决这个挑战。

我的代码:

var combiner = require('stream-combiner');
var stream = require('stream')
var split = require('split');
var zlib = require('zlib');

module.exports = function() {
    var ws = new stream.Writable({decodeStrings: false});
    function ResultObj() {
        name: '';
        books: [];
    }
    ws._write = function(chunk, enc, next) {
        if(chunk.length === 0) {
            next();
        }
        chunk = JSON.parse(chunk);
        if(chunk.type === 'genre') {
            if(currentResult) {
                this.push(JSON.stringify(currentResult) + '\n');
            }
            var currentResult = new ResultObj();
            currentResult.name = chunk.name;
        } else {
            currentResult.books.push(chunk.name);
        }

        next();

        var wsObj = this;

        ws.end = function(d) {
            wsObj.push(JSON.stringify(currentResult) + '\n');
        }
    }
    return combiner(split(), ws, zlib.createGzip());
}

我的代码不起作用并返回'无法管道。不可读'。有人能指出我哪里出错了吗?

欢迎任何其他关于如何改进的评论......

0 个答案:

没有答案