使用 rxJava 和改造多次调用另一个请求中的请求
Posted
技术标签:
【中文标题】使用 rxJava 和改造多次调用另一个请求中的请求【英文标题】:request in another request called several times with rxJava and retrofit 【发布时间】:2020-01-29 22:28:00 【问题描述】:我正在使用 MVVM 和 rxJava 和改造来发送我的请求。 我有一个底部导航视图,其中有 5 个片段,在其中一个片段中,我必须发送一个请求,然后发送响应,我必须向我的服务器发送另一个请求。 这是我的 ViewModel 类:
class MyViewModel: ViewModel()
val compositeDisposable = CompositeDisposable()
val myFirstReqLiveData = MutableLiveData<myFirstReqModel>()
val mySecondReqLiveData = MutableLiveData<mySecondReqModel>()
fun getFirstReq(token:String)
val firstReqDisposable = RetrofitClientInstance.getRetrofitInterface()
.getFirstReq(token)
.subscribeOn(Schedulers.io())
.observeOn(androidSchedulers.mainThread()).singleElement()
.subscribe(
it-> myFirstReqLiveData.value = it
,
errorFirstReqLiveData.value = it
,
)
compositeDisposable.add(firstReqDisposable)
fun getSecondReq(token:String)
val secondReqDisposable = RetrofitClientInstance.getRetrofitInterface()
.getSecondReq(token)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).singleElement()
.subscribe(
it-> mySecondReqLiveData.value = it
,
errorSecondReqLiveData.value = it
,
)
compositeDisposable.add(SecondReqDisposable)
override fun onCleared()
super.onCleared()
compositeDisposable.clear()
在我的片段中,我是这样实现的:
class FirstTabFragment : Fragment()
private lateinit var myViewModel: MyViewModel
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
myViewModel = ViewModelProviders.of(activity!!).get(MyViewModel::class.java)
getFirstReq(myViewModel, token!!)
observeFirstReq(myViewModel)
observeFirstReqError(myViewModel)
observeSecondReq(myViewModel)
observeSecondReqError(myViewModel)
fun getFirstReq(viewModel: MyViewModel, token: String)
viewModel.getFirstReq(token)
fun observeFirstReq(viewModel: MyViewModel)
viewModel.getFirstReqLiveData().observe(this, Observer myFirstReqModel ->
getSecondReq(myViewModel)
fun getSecondReq(viewModel: MyViewModel, token: String)
viewModel.getSecondReq(token)
fun observeSecondReq(viewModel: MyViewModel)
viewModel.getSecondReqLiveData().observe(this, Observer mySecondReqModel ->
//do some work with my data
我的问题是当我切换标签时,我的第二个请求被调用了多次。
我想我每次重新打开我的片段时都会分配一个新的订阅,所以它调用了几次。
我该如何解决这个问题?!
【问题讨论】:
getFirstReqLiveData 在您切换选项卡时收到通知。由于它正在为第二个请求进行 API 调用。您必须将可变的实时数据包装到 Event在下面创建类
open class Event<out T>(private val content: T)
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T?
return if (hasBeenHandled)
null
else
hasBeenHandled = true
content
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
在 Viewmodel 中像这样更改
val myFirstReqLiveData = MutableLiveData<Event<myFirstReqModel>>()
val mySecondReqLiveData = MutableLiveData<Event<mySecondReqModel>>()
在片段类中
fun observeFirstReq(viewModel: MyViewModel)
viewModel.getFirstReqLiveData().observe(this, EventObserver myFirstReqModel ->
getSecondReq(myViewModel)
改变
it-> myFirstReqLiveData.value = it to
it-> myFirstReqLiveData.value = Event(it)
如果对您有帮助,请尝试使用这种方式。
【讨论】:
你也可以分享EventObserver
的课程吗?!
class EventObserver您还可以从观察者中删除 getSecondReq(myViewModel)
并组合或链接您的请求。
https://github.com/ReactiveX/RxJava/wiki/Combining-Observables
类似这样的:
val disposable = RetrofitClientInstance.getRetrofitInterface()
.getFirstReq(token)
.doOnError errorFirstReqLiveData.value = it
.doOnNext myFirstReqLiveData.value = it
.flatMap t -> getSecondReq(token)
.doOnError errorSecondReqLiveData.value = it
.doOnNext mySecondReqLiveData.value = it
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).singleElement()
.subscribe()
compositeDisposable.add(disposable)
【讨论】:
我是 RxJava 新手,我会阅读并在未来使用您的答案,谢谢 @AzinNilchi 不客气 :) 这个链接非常有用,我经常查看它以查看所有可用选项以上是关于使用 rxJava 和改造多次调用另一个请求中的请求的主要内容,如果未能解决你的问题,请参考以下文章
带有 rxJava2 和改造的 UndeliverableException