【问题标题】:Wait for the already subscribed Observable等待已经订阅的 Observable
【发布时间】:2017-05-11 21:40:10
【问题描述】:

我通过订阅调用服务器并使用结果更新Activity1 的视图:

//from within Activity1
xxx = fetch.byId(id)
    .subscribe(new Subscriber<Model>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(Model model) {
          //update view with the model
        }
    });

所有这些都应该对用户不可见(没有进度对话框等)。

我想要更多的是处理对Activity1 的点击:点击后,我必须等待(显示进度对话框)xxx 接收model,然后启动Activity2(需要model 要显示的值)。如果点击发生在xxx 完成之后,那么我不必等待(因为它已经完成)并立即启动Activity2

如何优雅地等待已经订阅的 Observable?

【问题讨论】:

  • If the click happened after the xxx finished then I don't have to wait (because it's already done) and start the Activity2 right away。这部分我还是不知道:如果xxx完成了,你已经去Activity2 => 没有办法点击Activity1
  • 一切都发生在Activity1,Activity2对这个问题没有意义,只是一个动作的例子。

标签: android rx-java


【解决方案1】:

您可以通过使用zip 运算符来做到这一点。只有当所有压缩后的 observables 都发出时,它才会发出一个项目,即数据已加载并且用户单击了一个按钮。

fetch.byId(id)
        .zipWith(RxView.clicks(button)
                     .doOnNext(click -> showLoading()), // when user clicks the button, show your progress dialog
                (model, click) -> model // when both model is loaded and button is clicked, pass only the model forward
        )
        .subscribe(new Subscriber<Model>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Model model) {
                //update view with the model
                startActivity2()
            }
        });

【讨论】:

  • 我更喜欢combineLatest 而不是zip,因为它可以用于多次点击。如果您只需要它工作一次,那么使用fetch.byId(id).combineLatest(RxView.clicks(button)...).take(1).subscribe(...) 会更有效,因为 zip 会在获取期间缓冲所有点击。
【解决方案2】:

使用AsyncSubject 不是最好的解决方案,而是一个简单的解决方案。

AsyncSubject<Model> async = AsyncSubject.create();
fetch.byId(id).subscribe(async);
xxx = async.asObservable();
xxx.subscribe(this.subscriber);

然后你可以用doOnSubscribe()toCompletable()链接你想做的事情。

xxx.toCompletable()
   .doOnSubscribe(this::showProgress)
   .subscribe(this::goToActivity2, this::displayError);

【讨论】:

  • 实际上这应该可以,但即使没有主题也可以实现
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 2018-09-05
  • 1970-01-01
  • 2017-09-03
  • 1970-01-01
相关资源
最近更新 更多