我正在尝试使用RxJava避免vertx回调地狱。
但我有“rx.exceptions.OnErrorNotImplementedException: Cannot have multiple subscriptions
”。这有什么不对?
public class ShouldBeBetterSetter extends AbstractVerticle {
@Override
public void start(Future<Void> startFuture) throws Exception {
Func1<AsyncMap<String,Long>, Observable<Void>> obtainAndPutValueToMap = stringLongAsyncMap -> {
Long value = System.currentTimeMillis();
return stringLongAsyncMap.putObservable("timestamp", value)
.doOnError(Throwable::printStackTrace)
.doOnNext(aVoid -> System.out.println("succesfully putted"));
};
Observable<AsyncMap<String,Long>> clusteredMapObservable =
vertx.sharedData().<String,Long>getClusterWideMapObservable("mymap")
.doOnError(Throwable::printStackTrace);
vertx.periodicStream(3000).toObservable()
.flatMap(l-> clusteredMapObservable.flatMap(obtainAndPutValueToMap))
.forEach(o -> {
System.out.println("just printing.");
});
}
}
可以在此处找到工作Verticle(没有Rx): https://gist.github.com/IvanZelenskyy/9d50de8980b7bdf1e959e19593f7ce4a
答案 0 :(得分:1)
vertx.sharedData()。getClusterWideMapObservable(“mymap”)返回observable,它仅支持单个订阅者 - 因此异常。值得一试的一个解决方案是:
Observable<AsyncMap<String,Long>> clusteredMapObservable =
Observable.defer(
() -> vertx.sharedData().<String,Long>getClusterWideMapObservable("mymap")
);
这样每次调用clusteredMapObservable.flatMap()时,它都会订阅Observable.defer()返回的新的observable。
修改强>
如果可以使用相同的AsyncMap,正如@Ivan Zelenskyy指出的那样,解决方案可以
Observable<AsyncMap<String,Long>> clusteredMapObservable =
vertx.sharedData().<String,Long>getClusterWideMapObservable("mymap").cache()
答案 1 :(得分:1)
发生的事情是,在每次定期发布时,foreach
都会重新订阅您在上面定义的clusteredMapObservable
变量。
要解决此问题,只需将来电定位于定期信息流vertx.sharedData().<String,Long>getClusterWideMapObservable("mymap")
内的flatmap
即可。
这样的事情:
vertx.periodicStream(3000).toObservable()
.flatMap(l-> vertx.sharedData().<String,Long>getClusterWideMapObservable("mymap")
.doOnError(Throwable::printStackTrace)
.flatMap(obtainAndPutValueToMap))
.forEach(o -> {
System.out.println("just printing.");
});
更新
如果你不喜欢lambda的labmda,那就不要了。这是一个没有
的更新vertx.periodicStream(3000).toObservable()
.flatMap(l-> {
return vertx.sharedData().<String,Long>getClusterWideMapObservable("mymap");
})
.doOnError(Throwable::printStackTrace)
.flatMap(obtainAndPutValueToMap)
.forEach(o -> {
System.out.println("just printing.");
});
PS - 您对.flatMap(obtainAndPutValueToMap))
的呼叫也是lambda中的lambda - 您只是将其移动到一个函数中。