合并并处理两个不同类型的RxJava Observable

时间:2016-09-06 00:02:07

标签: android rx-java retrofit2

我的目标

我想检查服务器的令牌是否仍然有效,假设我只是通过调用此getter知道该信息:preferenceHelper.isTokenValid()。然后,如果令牌无效,请调用获取新令牌并在本地更新令牌的请求那么,继续下一个请求将该点发布到服务器。那是因为我需要一个有效的令牌来进行任何进一步的服务器请求。

假设我有两个返回Observable的服务器请求:

此请求旨在获取服务器令牌,然后在接收时更新它。

Observable<Response<EntityToken>> updateServerToken = retrofitApi.authenticate(username,password);

此请求旨在将当前位置发布到服务器,如果成功,则返回保存的点

Observable<Response<EntityPoint>> updateServerToken = retrofitApi.postPoint(point);

我目前面临的问题:

  • 需要合并的两个可观察对象来自不同类型
  • 仅在需要
  • 时执行令牌更新请求
  • 在执行发布点数请求之前等待令牌更新请求完成

我应该如何编写我的RxJava Observable以满足所有这些条件?

2 个答案:

答案 0 :(得分:1)

由于三次调用之间存在依赖关系,merge没有任何意义。相反,使用flatMap

Observable<Response<EntityPoint>> response = 
retrofitApi.isTokenValid()
.flatMap(isValid ->
     isValid
     ? Observable.just("")
     : retrofitApi.authenticate(username,password)
                  .doOnNext(token -> doSomethingWithTheToken(token)
)
.flatMap(dummy -> retrofitApi.postPoint(point));

答案 1 :(得分:1)

首先,我将创建一个方法来检查entityToken是否有效。如果有效,请使用Observable.just(),但必须以某种方式创建Response实例。如果无效,请使用您的需求 retrofitApi.authenticate()中的API调用服务器。无论采用哪种路径,方法 getTokenObservable()都会发出Observable&lt; Response&lt; EntityToken&gt;&gt;。

public Observable<Response<EntityToken>> getTokenObservable(EntityToken entityToken, String username, String password) {    
  boolean isTokenValid = preferenceHelper.isTokenValid(entityToken);
  if (isTokenValid) {
    //my assumption that you have something like this
    Response<EntityToken> responseToken = new Response<EntityToken>(); 
    responseToken.setEntityToken(entityToken);
    return Observable.just(new Response<EntityToken>(entityToken.class));
  } else {
    Observable<Response<EntityToken>> updateServerToken = retrofitApi.authenticate(username, password);
    return updateServerToken;
  }
}

然后在调用它时,使用flatMap(),它采用Observable&lt; Response&lt; EntityToken&gt;&gt;的emisssions。并返回Observable&lt; Response&lt; EntityPoint&gt;&gt;的排放量。订阅并正常进行。

Observable<Response<EntityToken>> updatePointObservable = getTokenObservable(entityToken, username, password);
updatePointObservable
.flatMap(new Func1<Response<EntityToken>, Observable<Response<EntityPoint>>>() {
    @Override
    public Observable<Response<EntityPoint>> call(Response<EntityToken> responseToken) { 
        EntityToken entityToken = responseToken.getEntityToken(); //my assumption
        saveTokenLocally(entityToken); //this is where you save your token locally, change to the right method that you have
        Observable<Response<EntityPoint>> updateServerTokenObservable = retrofitApi.postPoint(point, entityToken); //pass your entityToken to the call?
        return updateServerTokenObservable;     
    }
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Response<EntityPoint>>() {
    @Override
    public void onCompleted() {
        //your own logic
    }

    @Override
    public void onError(Throwable e) {
        //your own logic
    }

    @Override
    public void onNext(Response<EntityPoint> entityPoint) {
        //your own logic
    }
});