我有以下简单的代码:
let a: Observable<any> = Observable.from([1,2,3,4,5]).share();
let b: Subject<any> = new Subject();
a.subscribe(b)
a.subscribe(value => console.log("New observable value: " + value));
b.subscribe(value => console.log("New subject value: " + value));
b.next("value1");
b.next("value2");
我看到的唯一控制台行是对于数组中的每个值都具有“New observable value:”的控制台行。如果我注释掉第3行,那么我得到所有“新的可观察值”行和“新主题值”行,但是主题当然不会得到observable(数组的一部分)省略的任何值。
基本问题 - 这是为什么?为什么我的主题没有看到任何数组元素1,2,3,4,5?它订阅了observable,所以它应该得到这些事件(share()
应该向所有订阅者广播),但这似乎是我的误解。
我在这里寻找的是对主题进行单一订阅,并查看来自observable的所有值以及通过调用next()
发出的任何值。我的代码是错的,还是我试图以错误的方式做事?
答案 0 :(得分:2)
当您订阅console.log
已收到数据的Subject
时,您的基本问题就是订阅的顺序。 (查看下面的代码示例,看它是否正在运行)
第二个问题,即next("value1")
无效的原因,是因为a.subscribe(b)
在.complete()
发出后也会在b
上调用1,2,3,4,5
。
let a = Rx.Observable.from([1,2,3,4,5]).share();
let b = new Rx.Subject();
b.subscribe(value => console.log("New subject value: " + value));
a.subscribe(value => console.log("New observable value: " + value));
a.subscribe(b);
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
一种方式如何解决此问题:请勿订阅完整的Subject
,而只需订阅next
- 来电。但请记住,这只是一种方式来实现这一点,具体情况可能会有更好的解决方案。
let a = Rx.Observable.from([1,2,3,4,5]).share();
let b = new Rx.Subject();
b.subscribe(value => console.log("New subject value: " + value));
a.subscribe(value => console.log("New observable value: " + value));
a.subscribe(data => b.next(data));
b.next("value1");
b.next("value2");
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
答案 1 :(得分:1)
这是主题及其内部状态的经典问题。
当您致电pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
useHTML: true
}
}
时,主题会收到来自源Observable .highcharts-data-label span {
word-wrap:break-word;
white-space:pre-wrap!important;
}
的所有项目以及标记为已停止的a.subscribe(b)
通知。您可以在源代码中看到它:https://github.com/ReactiveX/rxjs/blob/master/src/Subject.ts#L86
然后忽略所有其他信号,您可以在此处看到:https://github.com/ReactiveX/rxjs/blob/master/src/Subject.ts#L56
这意味着此Subject实例将永远不会再发出任何内容。这是永远完成的。您可以看到a
信号确实是通过complete
运算符发送的:
complete
请参阅演示:https://jsbin.com/bepupor/1/edit?js,console
因此,在您的情况下,您希望保护主题do()
不接收a.do(val => console.log('do: ' + val), null, () => console.log('do: complete'))
.subscribe(b)
通知。您可以通过手动获取和仅推送b
信号来执行此操作:
complete
请参阅演示:https://jsbin.com/bepupor/4/edit?js,console
另一个非常类似的问题:Rx.Subject loses events