RxJava递归调用
我发现了一个非常有趣的例子,当您必须根据它发出的数据更改初始的RxJava递归调用,java,rx-java,rx-android,Java,Rx Java,Rx Android,我发现了一个非常有趣的例子,当您必须根据它发出的数据更改初始的可观察的 我有LocationManager,它提供了一个更新间隔不同的位置 enum LocationUpdateFrequency { HEIGHT, MEDIUM, LOW } interface LocationManager { Observable<Location> getLocationUpdates(LocationUpdateFrequency frequency); Loc
可观察的
我有LocationManager
,它提供了一个更新间隔不同的位置
enum LocationUpdateFrequency {
HEIGHT, MEDIUM, LOW
}
interface LocationManager {
Observable<Location> getLocationUpdates(LocationUpdateFrequency frequency);
LocationUpdateFrequency calcOptimalFrequency(Location currentLocation, Location prevLocation);
}
枚举位置更新频率{
高度,中等,低
}
接口位置管理器{
可观测的getLocationUpdates(LocationUpdateFrequency频率);
LocationUpdateFrequency calcOptimalFrequency(位置currentLocation,位置prevLocation);
}
所以我想用默认值MEDIUM订阅初始getLocationUpdate,在它生成2个位置之后,我想用新的最佳频率重新订阅
我有一个解决方案,但它使用了可变性:
class LocationState {
Location currentLocation;
Location pastLocation;
boolean isValid() {
return currentLocation != null && pastLocation != null;
}
}
class LocationAndFrequency {
final Location location;
final LocationUpdateFrequency frequency;
public LocationAndFrequency(Location location, LocationUpdateFrequency frequency) {
this.location = location;
this.frequency = frequency;
}
}
public Observable<Location> getOptimalLocationUpdates() {
final LocationManager locationManager = null;
final LocationState state = new LocationState();
return Observable.defer(() -> {
final LocationUpdateFrequency frequency;
if (state.isValid()) {
frequency = locationManager.calcOptimalFrequency(state.currentLocation, state.pastLocation);
} else {
frequency = LocationUpdateFrequency.MEDIUM;
}
return locationManager.getLocationUpdates(frequency)
.doOnNext(location -> {
state.pastLocation = state.currentLocation;
state.currentLocation = location;
})
.map(location -> new LocationAndFrequency(location, frequency));
})
.takeUntil(locationAndFrequency -> {
final LocationUpdateFrequency optimalFrequency =
locationManager.calcOptimalFrequency(state.currentLocation, state.pastLocation);
return locationAndFrequency.frequency != optimalFrequency;
})
.map(locationAndFrequency -> locationAndFrequency.location)
.repeat();
}
类位置状态{
位置当前位置;
地理位置;
布尔值有效(){
返回currentLocation!=null&&pastLocation!=null;
}
}
类别位置和频率{
最终位置;
最终位置更新频率;
公共位置和频率(位置位置、位置更新频率){
这个位置=位置;
这个频率=频率;
}
}
公共可观测的getOptimalLocationUpdates(){
最终位置管理器位置管理器=空;
最终位置状态=新位置状态();
返回可观察。延迟(()->{
最终位置更新频率;
if(state.isValid()){
频率=locationManager.calcOptimalFrequency(state.currentLocation,state.pastLocation);
}否则{
频率=LocationUpdateFrequency.MEDIUM;
}
返回locationManager.GetLocationUpdate(频率)
.doOnNext(位置->{
state.pastLocation=state.currentLocation;
state.currentLocation=位置;
})
.地图(位置->新位置和频率(位置,频率));
})
.takeUntil(位置和频率->{
最终位置更新频率最佳频率=
locationManager.calcOptimalFrequency(state.currentLocation、state.pastLocation);
返回位置和频率.frequency!=最佳频率;
})
.map(locationAndFrequency->locationAndFrequency.location)
.重复();
}
什么是更优雅的解决方案?getLocationUpdates是在值为on后完成的,还是在值到达时无限推送值?因为repeat,它看起来只会产生值。不,它是不定式,我使用takeUntil和repeat:只要选中的
getLocationUpdates
是最优的,就订阅,然后takeUntil将取消订阅,repeat将订阅新的最优。我希望实现相同的行为,而不具有易变性。你能看看这个impl吗?我正在使用一个主题,但这也可能发生变化:很棒的工作,非常好的示例,如何使用主题实现它。好奇的是,在没有主题和可变变量的情况下实现是可能的吗?好吧,我认为关键是订阅流,并总是在订阅时重播最后一个值。这是一个与主题类似的机械论。你可以看看我的另一个例子:。稍后我会将实现更改为不使用主题,并将其作为答案发布。