在 RxJava Android 中组合动态 API 请求

Posted

技术标签:

【中文标题】在 RxJava Android 中组合动态 API 请求【英文标题】:Combine dynamic API requests in RxJava Android 【发布时间】:2021-11-01 14:13:52 【问题描述】:

我想在一个 API 响应后循环多个 API 请求,并且在完成所有请求后我必须执行操作。

第一个 API 响应(getModels)=

 
    "message":
      "models":[
        
          "equipno":"000000000001027019",
        
        ,
        
          "equipno":"000000000001027020",
        
        ,
        
          "equipno":"000000000001027021",
        
        ,
        
          "equipno":"FL3-PINRO-0001/011",
          
        
]


    

然后我必须为在第一个 API 响应中收到的所有设备调用循环中的第二个 API。

第二个 API 响应(getPrediction)-

"body":
    "status":"success",
    "message":
      "equipno":"000000000001027019",
      "predictions":[
        
          "date":"2020-09-01",
          "maintenance":true,
          "accuracy":13.07
        
      ],
      "elapsed":0.03
    


我尝试使用以下 Rx java 代码,但它不起作用。

 val predictiveMaintenanceServiceCall = PredictiveMaintenanceServiceCall(context)
        val data = predictiveMaintenanceServiceCall.getModels(this).map  it.predictionMessage?.models?.map  it1 -> it1?.equipno  


        data.map  items ->
            items.map  item ->
                predictiveMaintenanceServiceCall.getPrediction(item, dateFormatter.format(Calendar.getInstance().time))
            
        
            .subscribeOn(Schedulers.io())
            .observeOn(androidSchedulers.mainThread())
            .subscribe( it ->
                Log.i("v ", "loadAlertsList zip $it.size")
                Observable.zip(it, Arrays::asList)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe( it ->
                        for (i in it as List<PredictionModel>)
                            Log.i("v ", "loadAlertsList $i.message?.equipno")

                    , 
                        Log.i("v ", "loadAlertsList $it")
                    )

            ,
                

                )
    
      

【问题讨论】:

【参考方案1】:

首先,如果 API 在您的控制范围内,那么我建议您将 getPrediction API 更新为 equipno 列表之外的 API,这样您就可以调用一次 API 并避免所有不必要的 API 调用。

至于目前如何做,我建议不要使用 RX,而是研究 kotlin 协程。您的问题可以通过以下步骤解决。

使您的改造功能可暂停

Retrofit 2.6.0 及以上版本支持挂起功能,所以您只需将您的getPredictiongetModel 用挂起修饰符标记为

suspend fun getModel(): List<Model>
suspend fun getPredication(equipno: String): List<Predication>

启动一个协程来调用 API(理想情况下这应该在 ViewModel 中完成)

private fun callAPI() = viewModelScope.launch 
    val models = getModels()
    models.forEach 
        val predication = getPrediction(it.equipno)
        // Do something with predication
    

【讨论】:

以上是关于在 RxJava Android 中组合动态 API 请求的主要内容,如果未能解决你的问题,请参考以下文章

android Retrofig RxJava写法基于Kotlin在优化

Android RxJava使用介绍 RxJava的操作符

Android函数响应式编程最新RxJava-操作符入门

android EventBus的简单使用

我们真的需要使用RxJava+Retrofit吗?

Android函数响应式编程最新RxJava-操作符入门