【问题标题】:Call parallel multiple the api request in the clean architecture在干净的架构中并行调用多个api请求
【发布时间】:2022-01-05 05:55:39
【问题描述】:

我在 viewModel 中有 5 个要并行调用的 api 调用函数,我该怎么做?我将每个函数都放在WithContext(Dispachers.IO) 中,但它不起作用。我使用协程流来调用 api。 注意:我使用了干净的架构模式,并且我只有一个用例

ViewModel 代码:

class MyJobsViewModel constructor(
    private val myJobsUseCases: MyJobsUseCases,
    private val clientNavigator: ClientNavigator
) : ViewModel(), ClientNavigator by clientNavigator {

    private val _state = mutableStateOf(MyJobsState())
    val state: State<MyJobsState> get() = _state


    private fun getAllJobs(
        offset: Int = 0,
        limit: Int = 10,
        type: JobTypeEnum = JobTypeEnum.ALL
    ) {
        myJobsUseCases.getJobsUseCase.invoke(offset = offset, limit = limit, type = type)
            .onEach {
                when (it) {
                    is Resource.Success -> _state.value =
                        state.value.copy(
                            isLoading = false,
                            allJobItems = it.data ?: JobItemsResponse()
                        )
                    is Resource.Error -> _state.value =
                        state.value.copy(
                            isLoading = false,
                            error = it.message ?: "An unexpected error occurred"
                        )
                    is Resource.Loading -> _state.value = state.value.copy(isLoading = true)
                }
            }.launchIn(viewModelScope)
    }

    private fun getActiveJobs(
        offset: Int = 0,
        limit: Int = 10,
        type: JobTypeEnum = JobTypeEnum.ALL
    ) {
        myJobsUseCases.getJobsUseCase.invoke(offset = offset, limit = limit, type = type)
            .onEach {
                when (it) {
                    is Resource.Success -> _state.value =
                        state.value.copy(
                            isLoading = false,
                            activeJobItems = it.data ?: JobItemsResponse()
                        )
                    is Resource.Error -> _state.value =
                        state.value.copy(
                            isLoading = false,
                            error = it.message ?: "An unexpected error occurred"
                        )
                    is Resource.Loading -> _state.value = state.value.copy(isLoading = true)
                }
            }.launchIn(viewModelScope)
    }

}

【问题讨论】:

    标签: android kotlin-coroutines


    【解决方案1】:

    并行多个调用的最佳方式是关注structured concurrency principle

    例如,当你需要评估5个独立网络请求的结果时:

    suspend fun fetchA(): Int { /* ... */ }
    suspend fun fetchB(): Int { /* ... */ }
    suspend fun fetchC(): Int { /* ... */ }
    suspend fun fetchD(): Int { /* ... */ }
    suspend fun fetchE(): Int { /* ... */ }
    
    suspend fun overallResult(): Int = coroutineScope {
        val a = async { fetchA() }
        val b = async { fetchB() }
        val c = async { fetchC() }
        val d = async { fetchD() }
        val e = async { fetchE() }
    
        a.await() + b.await() + c.await() + d.await() + e.await()
    }
    

    或者当你需要进行 5 次独立的 api 调用而不返回任何值时:

    suspend fun callA() { /* ... */ }
    suspend fun callB() { /* ... */ }
    suspend fun callC() { /* ... */ }
    suspend fun callD() { /* ... */ }
    suspend fun callE() { /* ... */ }
    
    suspend fun makeCalls(): Unit = coroutineScope {
        launch { callA() }
        launch { callB() }
        launch { callC() }
        launch { callD() }
        launch { callE() }
    }
    

    launchasync 块中的包装函数会生成一个新的协程并并行执行。

    coroutineScope 组织了可以使用启动和异步的区域。只有当每个子协程都完成时它才会完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2016-06-24
      • 2013-05-24
      • 1970-01-01
      • 2022-10-13
      • 1970-01-01
      • 2020-02-17
      相关资源
      最近更新 更多