You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保产品接口请求完成后再执行产品类型接口请求并处理数据?

问题描述

我开发了一款应用,需要调用两个接口:一个拉取产品列表,另一个拉取产品类型列表。第二个接口仅返回类型列表,但我需要在该列表开头添加“All”类型,并附上产品总数。

预期流程:

  • 调用产品列表接口,返回所有产品的JSON数据
  • 调用产品类型列表接口,返回所有类型数据

待类型数据返回后,要在列表开头添加“All”类型并统计产品总数,因此必须确保第一个接口请求完成后再处理第二个接口的结果。

当前初始化代码:

private var listOfProducts: List<Product> = emptyList()
private var listOfTypes: List<Type> = emptyList()
private var selectedType: String = ""

init {
   fetchProducts()
   fetchTypes()
}

请求方法实现:

fun fetchProducts() {
   viewModelScope.launch {
      API_CALL {
         listOfProducts = response
      }
   }
}
fun fetchTypes() {
   viewModelScope.launch {
      API_CALL {
         val nbProducts = listOfProducts.count()
         listOfTypes = Type("all", nbProducts) + response
      }
   }
}

由于网络延迟,fetchTypes中使用listOfProducts计数时可能失败,因为产品请求尚未完成。需要实现:要么阻止fetchTypes触发直到fetchProducts完成,要么同时发起两个请求,但等待前者完成后再处理后者的数据。


方案一:串行请求(先完成产品拉取,再发起类型请求)

调整初始化逻辑,让类型请求在产品请求完成后再执行,确保产品数据已就绪:

修改后的代码:

private var listOfProducts: List<Product> = emptyList()
private var listOfTypes: List<Type> = emptyList()
private var selectedType: String = ""

init {
   fetchProductsAndThenTypes()
}

private fun fetchProductsAndThenTypes() {
   viewModelScope.launch {
      // 先执行产品接口请求,确保数据写入listOfProducts
      API_CALL {
         listOfProducts = response
      }
      // 产品数据就绪后,发起类型请求并处理结果
      API_CALL {
         val nbProducts = listOfProducts.count()
         listOfTypes = Type("all", nbProducts) + response
      }
   }
}

也可以拆分保留原方法,将请求改为挂起函数,保证执行顺序:

init {
   viewModelScope.launch {
      fetchProducts()
      fetchTypes()
   }
}

private suspend fun fetchProducts() {
   API_CALL {
      listOfProducts = response
   }
}

private suspend fun fetchTypes() {
   API_CALL {
      val nbProducts = listOfProducts.count()
      listOfTypes = Type("all", nbProducts) + response
   }
}

这种方式逻辑直观,完全避免竞态问题,适合对请求顺序要求明确的场景。

方案二:并行发起请求,等待产品结果后处理类型数据

同时发起两个接口请求提升整体效率,等待产品请求完成后,再结合类型数据处理:

private var listOfProducts: List<Product> = emptyList()
private var listOfTypes: List<Type> = emptyList()
private var selectedType: String = ""

init {
   fetchDataInParallel()
}

private fun fetchDataInParallel() {
   viewModelScope.launch {
      // 同时发起两个异步请求
      val productsDeferred = async {
         API_CALL { response } // 直接返回产品列表结果
      }
      val typesDeferred = async {
         API_CALL { response } // 直接返回类型列表结果
      }

      // 先等待产品请求完成,拿到产品数据
      val products = productsDeferred.await()
      listOfProducts = products

      // 再获取类型数据,结合产品总数生成最终类型列表
      val types = typesDeferred.await()
      val nbProducts = products.count()
      listOfTypes = Type("all", nbProducts) + types
   }
}

这种方式两个接口同时请求,减少整体等待时间,同时保证处理类型数据时产品总数已就绪。


内容的提问来源于stack exchange,提问作者Seb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:30:00