这是测试代码
final Flowable<Integer> f1 = Flowable.fromPublisher(s -> {
s.onNext(Integer.valueOf(1));
s.onComplete();
});
final Flowable<Integer> f2 = Flowable.fromPublisher(s -> {
s.onNext(Integer.valueOf(2));
s.onComplete();
});
Flowable.zip(f1, f2, (i1, i2) -> "" + i1 + i2)
.blockingSubscribe(System.out::println);
它会得到
Exception in thread "main" java.lang.NullPointerException
at io.reactivex.internal.operators.flowable.FlowableZip$ZipSubscriber.onNext(FlowableZip.java:386)
我不明白为什么?
如果我像这样更新代码
final Flowable<Integer> f1 = Flowable.<Integer>fromPublisher(s -> {
s.onNext(Integer.valueOf(1));
s.onComplete();
}).onErrorResumeNext(Flowable.empty());
final Flowable<Integer> f2 = Flowable.<Integer>fromPublisher(s -> {
s.onNext(Integer.valueOf(2));
s.onComplete();
}).onErrorResumeNext(Flowable.empty());
Flowable.zip(f1, f2, (i1, i2) -> "" + i1 + i2)
.blockingSubscribe(System.out::println);
它将按预期打印12。但为什么?它没有意义。
答案 0 :(得分:1)
问题是,您使用Publisher<T>
违反了fromPublisher
的合同。
发布商需要按照Reactive Streams
合同中指定的非常具体的方式行事。这种行为包括在进行任何其他呼叫之前呼叫Subscriber.onSubscribe()
并尊重该用户的背压。
由于您没有致电onSubscribe
,因此内部queue
变量永远不会被初始化,而queue.offer
方法中对onNext
的调用会导致NPE。
据推测,通过使用onErrorResumeNext
,实施可以确保所有内容都得到正确调用,并且可以确保&#39;无效的状态。
要解决您的问题,有两种可能:
Flowable.fromPublisher
。它旨在与Reactive Streams宣言的其他实现相桥接,并且没有任何安全措施。而是使用正确处理初始化和背压的Flowable.create
。Observable
,因为您的用例似乎不关心背压。再次使用Observable.create
方法安全使用。