RxJava同时删除操作

时间:2018-05-04 13:28:23

标签: android rx-java rx-java2

我有一个问题,试图以一种被动的方式理解同一个观察者的同时操作应该如何运作。

方案如下:

我有一个用户列表和一个删除按钮。  每当我按remove时,我都会调用API:UsersApi.removeUser。可以同时删除多个用户。这意味着多个UsersApi.removeUser同时发生。

每次UsersApi.removeUser后,我需要进行UsersApi.refreshUser来电

因此,就伪代码而言,点击删除时我正在做的事情如下:

主讲人:

public Observable<User> removeUser(int userId) {
        return UsersApi.removeUser(userId)
                .flatMap(user -> UsersApi.refreshUser(userId));
    }

片段:

public void removeUser() {
   presenter.removeUser(userId)
     .subscribe(user -> {
        //remove user from ui
        // update number of total users
   })
}

这种方法的问题在于,由于remove的异步性质(允许多次删除),我无法保证到达订阅的内容是最新的。订阅将达到两次,每次删除一次,用户信息可能不会更新或最新。这有意义吗?

我想要发生什么:

  1. 并行/同时使用被动方法删除呼叫(由用户多次删除点击触发)
  2. 删除通话结束后,启动下一个删除通话
  3. 编辑:我想知道的是如何做/如果可以使用Rx运算符做我做的解决方案(参见edit2)。

    Edit2:我的解决方案是将用户操作排入队列(在这种情况下为remove),并在UsersApi.refreshUser(userId)调用完成时使用PublishSubject发出。

    基本上我所做的是(伪代码):

    private final PublishSubject<UserOperation> userOperationObs;
    private final ConcurrentLinkedQueue<UserOperation> pendingOperations;
    private boolean executingOperation;
    
    private void emitUserOperation(final UserOperation operation) {
          if (!executingOperation) {
                executingOperation = true;
                userOperationObs.onNext(operation);
            } else {
                executingOperation.add(operation);
            }
        }
    
    public Observable<User> removeUser(UserOperation operation) {
            return UsersApi.removeUser(operation.getUserId)
                    .switchMap(user -> UsersApi.refreshUser(operation.getUserId))
                    .doOnNext(user -> {
                       executingOperation = false;
                       final UserOperation nextOperation = pendingOperations.poll();
                       if (nextOperation != null) {
                           userOperationObs.onNext(operation);
                       }
    };
        }
    

1 个答案:

答案 0 :(得分:0)

您可以将用户界面的点击变为“可观察”(例如,通过使用RxBinding)。之后,您可以使用concatMap运算符执行api调用,以便在当前api调用完成后它将开始下一个网络调用。

// emit clicks as stream
Observable<?> clicks = RxView.clicks(removeView)

// listen clicks then perform network call in sequence
clicks.concatMap(ignored -> usersApi.refreshUser(userId))