如何将单个输出传递给RxJava中的complet?

时间:2018-12-05 13:07:42

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

我想调用API api1,并将API返回的输出传递给第二个API api2。第一个API是获取请求,第二个API是POST请求。因此,api1返回Single<String>,而api2返回Completable

函数看起来像这样:

// api1
public Single<String> getToken() {
  ...
}
// api2
public Completable saveTokenToBackend(String token, String userId) {
 ...
}

我想将这两个操作链接在一起。订户仅想知道获取令牌并保存令牌的过程是否成功。因此,最后一个操作链的返回类型应为Completable。但是,当我这样做时,API调用api2就会停止。根据日志,只有api1成功工作。

Single<Completable> r1 = getToken().map(t -> saveTokenToBackend(t, userId));
Completable r2 = Completable.fromSingle(r1);

我在这里的更广泛的问题是,我如何将响应从单一链接到完成?

第二个问题是为什么上面的代码不起作用?

:: EDIT ::

根据评论中的建议,我尝试了:

public Completable getAndSaveToken() {
    getToken().flatMapCompletable(t -> saveTokenToBackend(t, "dummyuser");
}

我正在使用我的应用代码:

getAndSaveToken()
   .subscribeOn(Schedulers.io())
   .observeOn(AndroidSchedulers.mainThread())
   .subscribe(() -> {
                Log.v(TAG, "call success");
    }, error -> {
                Log.e(TAG, "Error", error);
    });

结果:java.io.IOException: Must not be called on the main application thread

1 个答案:

答案 0 :(得分:2)

您有2个不同的问题,组成和安排。上下文:getToken返回单个,而saveToken(token)返回一个完成。

组成:要组成一个和一个可完成对象,您已经注意到,可以使用flatMap运算符,这将返回一个新的可完成对象,该对象首先获取令牌,然后将其保存(可能是,则需要在保存令牌之前对其进行修改;)

getToken().flatMapCompletable(n -> saveToken(n)) // returns a completable

如果您希望将其保留为单个,则可以将其映射回第一个实例:

getToken().flatMap(n -> saveToken(n).toSingleDefault(n)) // returns a single

计划:在android中,您不得在主线程中启动请求。为了避免这种情况,您可以使用subscribeOn运算符,看起来您已经注意到了

getToken().subscribeOn(io()).doOnNext(n -> {/*this should be evaluated in io thread*/})
getToken().subscribeOn(io()).observeOn(mainThread()).doOnNext(n -> {/*this on mainThread*/})

如果仍然出现错误,则说明observeOnsubscribeOn已在某处重新配置。需要更多代码以确保。但是无论如何,您都可以断言两次请求都在io线程中应用了两次运算符来执行:

getToken().subscribeOn(io).flatMapCompletable(token -> saveToken(token).subscribeOn(io()))

如果正在使用改造,另一种选择是使用RxJava2CallAdapterFactory工厂而不是默认工厂来应用createWithScheduler(io())。这将断言所有请求都是在io()中创建的,因此您可以合并并准备数​​据,最后应用observeOn(mainThread())来更新UI。