Retrofit + RxJava 中的链接请求
Posted
技术标签:
【中文标题】Retrofit + RxJava 中的链接请求【英文标题】:Chaining requests in Retrofit + RxJava 【发布时间】:2016-08-15 13:39:27 【问题描述】:我有 2 个 API,我想按顺序发出请求并将它们的数据存储在 SQLite 中。
首先我想向 API A
发出请求并将其数据存储在 SQL 表 a
中。然后向 APIB
发出请求,并将其数据存储在表 b
中,并将一些数据存储在表 a_b
中。 a_b
中存储的数据仅来自请求 B
。
如何使用 RxJava 做到这一点。我在某处读到了关于为此使用 flatMap 的信息,类似这样的
apiService.A()
// store in DB here? How? maybe use map()?
.flatMap(modelA ->
// or maybe store modelA in DB here?
return apiService.B().map(modelB ->
storeInDB()l // store B here ?
return modelB;
);
);
如果我不使用 lambda 函数,这看起来和普通的嵌套调用一样难看。这是更好的方法吗?
【问题讨论】:
【参考方案1】:我不认为使用 map
运算符是处理诸如存储 api 调用结果之类的最佳方法。
我喜欢做的是在 doOnNext
运算符中分离这些东西。所以你的例子是这样的:
apiService.A()
.doOnNext(modelA -> db.store(modelA))
.flatMap(modelA -> apiService.B())
.doOnNext(modelB -> db.store(modelB));
(添加必要的 observeOn
和 subscribeOn
自己,就像你需要它们一样)
【讨论】:
我不知道 Rx 的do
运营商。阅读其文档后,doOnComplete
不是更好的功能吗?
@Sourabh 这取决于您的Observable
。如果在从 api 成功调用后调用 onComplete
,则可以。如果您的Observable
可以发出多个事件,那么您应该选择doOnNext
。在您的情况下(Retrofit
)使用doOnNext
和doOnComplete
将得到相同的结果,但实际上doOnComplete
可能更直观(我出于纯粹的习惯使用doOnNext
)。
我的意思是,使用doOnComplete
而不是flatMap
...B()
不依赖于A()
的结果(SO 的 5 分钟评论编辑时间)
使用doOnComplete
而不是flatMap
是错误的,因为doOnComplete
不会更改流中的Observable
,而flatMap
会。换句话说,如果你使用flatMap
,你可以只使用一个subscribe
,而试图使用doOnComplete
而不是这个会迫使你在这个apiService.B().subscribe(...)
中调用apiService.B().subscribe(...)
doOnComplete
(这看起来很难看) 【参考方案2】:
是的,您可以将 flatmap 用于此目的。看下面的例子(假设你的服务A返回Observable<FooA>
,服务B返回Observable<FooB>
)
api.serviceA()
.flatMap(new Func1<FooA, Observable<FooB>>()
@Override
public Observable<FooB> call(FooA fooA)
// code to save data from service A to db
// call service B
return api.serviceB();
)
.subscribeOn(Schedulers.io())
.observeOn(androidSchedulers.mainThread())
.subscribe(new Subscriber<FooB>()
@Override
public void onCompleted()
@Override
public void onError(Throwable e)
@Override
public void onNext(FooB fooB)
// code to save data from service B to db
);
【讨论】:
如果我在 onNext 中编写代码将数据保存到数据库,它将在主线程上运行,对吗?如何在后台线程上将数据保存到数据库? 加入另一个flatMap
运算符。 api.serviceA().flatMap((FooA) -> // call service B).flatMap((FooB) -> // save data from service B and return a observable stating success / failure).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).doOnNext((isSuccess) -> // Only this will execute on main thread)
你会如何在 RxJava2 中做到这一点?以上是关于Retrofit + RxJava 中的链接请求的主要内容,如果未能解决你的问题,请参考以下文章
Glide工具类/OkGo网络请求/MVP请求数据/Retrofit+RxJava/ARouter/补间动画/轮播图等等等等等 记录一下~~
Glide工具类/OkGo网络请求/MVP请求数据/Retrofit+RxJava/ARouter/补间动画/轮播图等等等等等 记录一下~~
Glide工具类/OkGo网络请求/MVP请求数据/Retrofit+RxJava/ARouter/补间动画/轮播图等等等等等 记录一下~~