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' } ]