最近我开始使用Reactive extensions的硬件项目。我已经阅读了一些介绍和教程,但我仍然处于初级水平。根据{{3}}文章:
一切都是流
然而,我目前的理解(或心理障碍)告诉我,任何改变状态的操作(例如从存储库中删除数据)都不应该/返回流/可观察的。
关于我的域名的小背景:我有一个用于注册地理围栏的用例。从this开始,我会跟踪存储库中的活动地理围栏。有时应用程序需要删除地理围栏,因此实现此目的的基本步骤是:
我目前的解决方案如下:
geofenceRepository.get(id)
.map(new Func1<Geofence, String>() {
@Override
public String call(Geofence geofence) {
geofenceRepository.delete(geofence.getId()); // synchronous call here
return geofence.getRequestId();
}
})
.toList()
.flatMap(new Func1<List<String>, Observable<Status>>() {
@Override
public Observable<Status> call(List<String> ids) {
return locationProvider.removeGeofences(ids);
}
});
其中Geofence是我的自定义数据结构,locationProvider来自geofences do not survive reboot。
您会注意到数据检索是以stream / observable的形式实现的,与delete不同。
上面例子中我不喜欢的是:带this nice library的地图运算符
side effect我的意思是:
使用异步数据流进行编程
答案 0 :(得分:0)
反应很好,我认为这种情况很完美。
我认为你真正想要做的就是确保你的每个操作员完全 1 。就像你说的那样,flatMap也在消除你的地理围栏。
尝试使用链中的onNext
运算符进行删除。你要做什么检索它,它看起来像geofenceRepository.get(id)
,用运算符删除它,然后从locationProvider中删除它。也许是这样的:
geofenceRepository.get(id)
.map(new Func1<Geofence, String>() {
@Override
public String call(Geofence geofence) {
return geofence.getRequestId();
}
})
.doOnNext(new Action1<String>){
@Override
public void call(final String geoFenceId) {
geofenceRepository.delete(geofence.getId());
}
})
.doOnNext(new Action1<String>() {
@Override
public void call(final String geoFenceId) {
return locationProvider.removeGeofences(ids);
}
});
您可能真正想要做的是创建两个订阅者。这样,如果你想观察一个或两个的状态,你可以。您可以组合每个的状态。它取决于是否从存储库中删除并从提供程序中删除是独立的。
Observable<String> getFence = geofenceRepository.get(id)
.map(new Func1<Geofence, String>() {
@Override
public String call(Geofence geofence) {
return geofence.getRequestId();
}
});
getFence.subscribe(new Action1<String>){
@Override
public void call(final String geoFenceId) {
geofenceRepository.delete(geofence.getId());
}
});
getFence.map(new Func1<String, Status>() {
@Override
public Status call(final String geoFenceId) {
return locationProvider.removeGeofences(ids);
}
}).subscribe(new Action1<Status>(){
@Override
public void call(final Status status(){
//Handle your status for each removal
}
});
答案 1 :(得分:0)
我没有发现您的方法存在任何问题,而且更具反应性意味着更多API使用/返回Observables。你可以在任何lambdas中产生副作用,但是当你改变一个值时要小心,因为如果涉及异步,同一个对象可能会在管道的不同阶段同时发生变异。通常,我们使用不可变或有效不可变值来避免此问题。没有必要拆分您的活动,因此建议的doOnNext
分离是特定开发人员的偏好
如果您的geofenceRepository.delete
的某个版本返回某种类型的Observable
,则可以通过flatMapping覆盖它来更加反应:
get(id)
.flatMap(f -> geoFence.deleteAsync(f.getId()).map(v -> f.getRequestId()))
.toList()
.flatMap(...)
.subscribe(...)
在这里,deleteAsync
将返回Observable<Void>
,完成后将使用requestId恢复主序列。