我有一个observable,它使用scan
运算符进行转换,因此它总是根据当前值和前一个值(或初始值)发出一个值。
Subject<String> subject = PublishSubject.create();
Observable<String> observable = subject.scan("zero", (a, b) -> a + ", " + b);
然后,第一个观察者订阅,打印所有发出的值,并在一段时间后取消订阅。
Disposable first = observable.subscribe(System.out::println); // "zero"
subject.onNext("one"); // "zero, one"
first.dispose();
稍后,另一位订阅者订阅:
Disposable second = observable.subscribe(System.out::println); // "zero"
subject.onNext("two"); // "zero, one"
second.dispose();
正如您所看到的,每个观察者首先被提供初始值,并且在订阅前一个时发出的值消失了。我想要实现的是将scan
运算符中的状态保留在所有订阅中:
Disposable first = observable.subscribe(System.out::println); // "zero"
subject.onNext("one"); // "zero, one"
first.dispose();
Disposable second = observable.subscribe(System.out::println); // "zero, one"
subject.onNext("two"); // "zero, one, two"
second.dispose();
RxJava中是否有解决此问题的方法?
答案 0 :(得分:1)
我通过引入BehaviorSubject
作为“缓存”层找到了解决方案。不确定这是否是解决问题的最简洁方法,但它确实有效。
该行:
Observable<String> observable = subject.scan("zero", (a, b) -> a + ", " + b);
必须转变为:
Subject<String> observable = BehaviorSubject.create();
subject.scan("zero", (a, b) -> a + ", " + b)
.subscribe(observable);
答案 1 :(得分:1)
您可以扫描到BehaviorSubject
,其他人应该订阅:
Subject<String> subject = PublishSubject.create();
Observable<String> observable = subject.scan("zero", (a, b) -> a + ", " + b);
Subject<String> multicast = BehaviorSubject.create();
observable.subscribe(multicast);
Disposable first = multicast.subscribe(System.out::println); // "zero"
subject.onNext("one"); // "zero, one"
first.dispose();
Disposable second = multicast.subscribe(System.out::println); // "zero, one"
subject.onNext("two"); // "zero, one, two"
second.dispose();
答案 2 :(得分:1)
另一种解决方案:
observable#publish会将结果多播到所有订阅者,因此会保留最后的#scan值。您的解决方案无效,因为每次订阅时都会创建一个新的Observable。扫描值未保留。
@Test
void name3231() {
Subject<String> subject = PublishSubject.create();
Observable<String> observable = subject.scan("zero", (a, b) -> a + ", " + b);
ConnectableObservable<String> observableMulticast = observable.publish();
Disposable connect = observableMulticast.connect(); // must be disposed by hand
TestObserver<String> test = observableMulticast.test();
Disposable first = observableMulticast.subscribe(System.out::println); // "zero"
subject.onNext("one"); // "zero, one"
first.dispose();
test.assertValues("zero, one");
Disposable second = observableMulticast.subscribe(System.out::println); // "zero, one"
subject.onNext("two"); // "zero, one, two"
second.dispose();
test.assertValues("zero, one", "zero, one, two");
}