RxJava;如何同步发出可观察量

时间:2016-01-28 13:11:34

标签: java rx-java

我想同步发出两个Observable对象(它们是异步的),一个接一个地返回第一个发出的Observable对象。如果第一个失败,则不应发出第二个。

我们假设我们有一个Observable签署用户,另一个Observable自动选择用户的帐户,登录后。

这就是我的尝试:

public Observable<AccessToken> signInAndSelectAccount(String username, String password)
{

    Observable<AccessToken> ob1 = ...; // Sign in.
    Observable<Account> ob2 = ...; // Select account.


    return Observable.zip(
            ob1,
            ob2,
            new Func2<AccessToken, Account, AccessToken>() {
                @Override
                public AccessToken call(AccessToken accessToken, Account account)
                {
                     return accessToken;
                }
            });
}

遗憾的是,这对我的用例不起作用。它将以&#39; ob1&#39;

开始并行发出/调用两个可观察对象

有人遇到过类似的用例吗?或者有一个关于如何让observables以同步的方式等待彼此的想法,在那里可以返回第一个发出的?

提前致谢。

5 个答案:

答案 0 :(得分:6)

您也可以使用rx.observables.BlockingObservable例如:

BlockingObservable.from(/**/).single();

答案 1 :(得分:4)

在反应式编程中没有“等待”这样的术语。您需要考虑创建数据流,其中一个Observable可能被另一个数据流触发。收到token后,您需要收到account。它看起来像这样:

Observable<Account> accountObservable = Observable.create(new Observable.OnSubscribe<AccessToken>() {
    @Override public void call(Subscriber<? super AccessToken> subscriber) {
        subscriber.onNext(new AccessToken());
        subscriber.onCompleted();
    }
}).flatMap(accessToken -> Observable.create(new Observable.OnSubscribe<Account>() {
    @Override public void call(Subscriber<? super Account> subscriber) {
        subscriber.onNext(new Account(accessToken));
        subscriber.onCompleted();
    }
}));

答案 2 :(得分:1)

我不懂Java,但Scala中的解决方案可能就是这样,希望它对你来说是可读的

import rx.lang.scala.Observable

class AccessToken
class Account

case class TokenAndAccount(token: AccessToken, account: Account)

val accessTokenSource = Observable.just(new AccessToken)
val accountSource = Observable.just(new Account)

accessTokenSource
   .flatMap(token ⇒ accountSource.map(account ⇒ TokenAndAccount(token, account)))
   .subscribe(tokenAndAccount ⇒ println(tokenAndAccount))

基本上flatMap将确保仅在accountSource.map...的令牌发出后才使用accessTokenSource。在accountSource.map内,我们将获得的令牌和帐户合并在一起,以便以后在subscribe中使用。

flatMap是最有用的操作符之一,请务必阅读它的文档以及一些教程。

答案 3 :(得分:1)

您可以使用Single.blockingGet进行同步通话

// example 
signIn(name,password).blockingGet() 

答案 4 :(得分:0)

此外,我们可以在 .toBlocking() 中使用 Observable 方法,这将成为 BlockingObservable。即,

Observable.just().toBlocking();