【问题标题】:State mutation in reactive way反应方式的状态突变
【发布时间】:2015-09-11 14:11:26
【问题描述】:

最近我开始使用Reactive extensions 的android 项目。我已经阅读了一些介绍和教程,但我仍然处于初学者的水平。根据this文章:

一切都是流

但是我目前的理解(或心理障碍)告诉我,任何改变状态的操作(例如从存储库中删除数据)都不应该是/返回流/可观察的。

关于我的域的一些背景知识:我有一个注册地理围栏的用例。自geofences do not survive reboot 以来,我一直在跟踪存储库中的活动地理围栏。有时应用需要移除地理围栏,因此实现此目的的基本步骤是:

  • 从存储库中检索地理围栏
  • 从设备中移除地理围栏
  • 从存储库中删除地理围栏

我目前的解决方案如下:

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 来自this nice library

您会注意到,与删除不同,数据检索是作为流/可观察实现的。

我不喜欢上面例子中的:map operator with side effect

问题

  • 什么是更“被动”的更好解决方案,我在这里缺少什么?
  • 使用响应式方法是否有意义?

reactive programming 我的意思是:

使用异步数据流编程

【问题讨论】:

    标签: android state reactive-programming rx-java rx-android


    【解决方案1】:

    我认为您的方法没有任何问题,更具反应性意味着更多 API 使用/返回 Observables。您可以在任何 lambda 表达式中产生副作用,但在更改值时要小心,因为如果涉及异步,同一对象可能会在管道的不同阶段同时发生变异。通常,我们使用不可变或有效不可变的值来避免这个问题。没有真正需要拆分您的活动,因此建议的 doOnNext 拆分是特定开发人员的偏好

    如果您的 geofenceRepository.delete 有一个返回某种 Observable 的版本,您可以通过对其进行 flatMapping 来提高反应性:

    get(id)
    .flatMap(f -> geoFence.deleteAsync(f.getId()).map(v -> f.getRequestId()))
    .toList()
    .flatMap(...)
    .subscribe(...)
    

    这里,deleteAsync 将返回一个 Observable&lt;Void&gt;,当它完成时,将使用 requestId 恢复主序列。

    【讨论】:

      【解决方案2】:

      Reactive 很棒,我认为这种情况很完美。

      我认为您在这里真正想做的是确保您的每个操作员都准确地完成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
                 }
              });
      

      【讨论】:

        猜你喜欢
        • 2017-11-19
        • 2019-07-25
        • 1970-01-01
        • 2017-08-11
        • 2021-11-28
        • 1970-01-01
        • 1970-01-01
        • 2020-01-09
        • 2019-03-27
        相关资源
        最近更新 更多