Javascript 如何使用highland.js分流?

Javascript 如何使用highland.js分流?,javascript,typescript,stream,highland.js,Javascript,Typescript,Stream,Highland.js,我有一个由BaseData对象组成的sourceStream 我想把这个流分成n——不同数量的流,然后过滤和转换每个BaseData对象,使其符合自己的喜好 最后,我希望n流只包含特定类型,分叉流的长度可以不同,因为将来可能会删除或添加数据 我想我可以通过fork设置它: import * as _ from 'highland'; interface BaseData { id: string; data: string; } const sourceStream = _(

我有一个由
BaseData
对象组成的
sourceStream

我想把这个流分成
n
——不同数量的流,然后过滤和转换每个
BaseData
对象,使其符合自己的喜好

最后,我希望
n
流只包含特定类型,分叉流的长度可以不同,因为将来可能会删除或添加数据

我想我可以通过
fork
设置它:

import * as _ from 'highland';

interface BaseData {
    id: string;
    data: string;
}

const sourceStream = _([
    {id: 'foo', data: 'poit'},
    {id: 'foo', data: 'fnord'},
    {id: 'bar', data: 'narf'}]);

const partners = [
    'foo',
    'bar',
];

partners.forEach((partner: string) => {
    const partnerStream = sourceStream.fork();

    partnerStream.filter((baseData: BaseData) => {
        return baseData.id === partner;
    });

    partnerStream.each(console.log);
});
我希望现在有两个流,
foo
-流包含两个元素:

{ id: 'foo', data: 'poit' }
{ id: 'foo', data: 'fnord' }
以及
-流,以包含一个元素:

{ id: 'bar', data: 'narf' }
但我得到了一个错误:

/usr/src/marketing-tasks/node_modules/highland/lib/index.js:1338
        throw new Error(
        ^

Error: Stream already being consumed, you must either fork() or observe()
    at Stream._addConsumer (/usr/src/marketing-tasks/node_modules/highland/lib/index.js:1338:15)
    at Stream.consume (/usr/src/marketing-tasks/node_modules/highland/lib/index.js:1500:10)
    at Stream.each (/usr/src/marketing-tasks/node_modules/highland/lib/index.js:1774:18)
    at partners.forEach (/usr/src/marketing-tasks/dist/bin/example.js:17:19)
    at Array.forEach (native)
    at Object.<anonymous> (/usr/src/marketing-tasks/dist/bin/example.js:12:10)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
仅打印:

foo
{ id: 'foo', data: 'poit' }
{ id: 'foo', data: 'fnord' }
bar
而不是预期的:

foo
{ id: 'foo', data: 'poit' }
{ id: 'foo', data: 'fnord' }
bar
{id: 'bar', data: 'narf'}

也可能是我误解了fork的意思。根据:

fork()分叉流,允许您添加其他使用者 有共同的背压。分流到多个用户的流将 只有最慢的消费者才能以最快的速度从源中提取值 处理它们

注意:不要依赖于分叉之间的一致执行顺序。 此转换仅保证所有fork都将处理一个值foo 在任何之前,将处理第二个值栏。它不能保证 forks处理foo的顺序

提示:修改fork(或)中的流值时要小心 使用这样做的库)因为相同的值将传递给 每个fork中,在一个fork中所做的更改都将在任何 之后执行。添加不一致的执行顺序,以及 最终可能会出现一些微妙的数据损坏错误。如果需要修改 如果有任何值,则应制作副本并修改副本

弃用警告:当前可以在 使用它(例如,通过转换)。这将不再可能 在下一个主要版本中。如果你要岔开一条小溪,总是 打电话给福克


因此,与“如何分叉流”不同,我实际的问题可能是:如何将highland流动态复制到不同的流中?

partnerStream.filter()
返回一个新流。然后,您再次使用
partnerStream.each()
,而不调用
fork()
observe()
,使用
partnerStream.each()
。因此,要么将
partnerStream.filter().each()
调用链接起来,要么将
partnerStream.filter()
的返回值赋给一个变量,然后调用
。在创建所有分叉之前,必须记住不要使用分叉流。就像一个人消费一个分叉流,它和它的“父代”将被消费,使得任何后续的分叉都从一个空流分叉

const partnerStreams: Array<Stream<BaseData>> = [];

partners.forEach((partner: string) => {
    const partnerStream = sourceStream
        .fork()
        .filter((item: BaseData) => {
            return item.id === partner;
         }
    );

    partnerStreams.push(partnerStream);
});

partnerStreams.forEach((stream, index) => {
    console.log(index, stream);
    stream.toArray((foo) => {
        console.log(index, foo);
    });
});

我已经更新了我的问题,因为现在我没有看到错误,但是我只看到一个流的返回值,而不是两个流的返回值。
const partnerStreams: Array<Stream<BaseData>> = [];

partners.forEach((partner: string) => {
    const partnerStream = sourceStream
        .fork()
        .filter((item: BaseData) => {
            return item.id === partner;
         }
    );

    partnerStreams.push(partnerStream);
});

partnerStreams.forEach((stream, index) => {
    console.log(index, stream);
    stream.toArray((foo) => {
        console.log(index, foo);
    });
});
0 [ { id: 'foo', data: 'poit' }, { id: 'foo', data: 'fnord' } ]
1 [ { id: 'bar', data: 'narf' } ]