在使用 rxJava 和改造多次调用的另一个请求中请求

request in another request called several times with rxJava and retrofit

我正在使用 MVVM 和 rxJava 以及改造来发送我的请求。 我有一个底部导航视图,它有 5 个片段,在其中一个片段中,我必须发送一个请求,然后发送响应,我必须向我的服务器发送另一个请求。 这是我的 ViewModel class :

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
    }
   }

我的问题是当我切换标签时,我的第二个请求调用了好几次。

我想我每次重新打开我的片段时都会分配一个新的订阅,所以它调用了几次。

我该如何解决这个问题?!

在下面创建 class

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>>()

在片段中 class

fun observeFirstReq(viewModel: MyViewModel) {
    viewModel.getFirstReqLiveData().observe(this, EventObserver { myFirstReqModel ->
   getSecondReq(myViewModel)
    }
   }

改变

it-> myFirstReqLiveData.value = it to 
it-> myFirstReqLiveData.value = Event(it)

尝试使用这种方式,如果这对你有帮助的话。

您还可以从观察者中删除 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)