Kotlin 协程。 运行 API 调用完成时的代码

Kotlin coroutines. Run code when API calls finish

我担心 coroutines。我想做的是在完成几个请求后执行特定代码......在我使用 completionHandlers 并正常工作之前,问题是有更多的请求,我不想嵌套它们,我认为这不是正确的做法......所以我不知道你是否对这个练习有什么建议。我提出以下建议,但我不确定它是否是最好的:

  val job = viewLifecycleOwner.lifecycleScope.launch {
             // API calls
             Process1 (view)
             Process2 (view)
             Process3 (view)
             Process4 (view)
         }
         runBlocking {
             job.join ()
             // Continue normally
         }

感谢阅读!

Ps。每个“进程”调用 API 并响应为 completionHandler

这是一个简单的示例,其中包含 2 种不同的 return 从协同程序中获取值的方法。 您无法保证协程何时 return 或完成,因此您必须具有某种回调函数来处理您的 api return 数据,或者您可以使用 withContext 方法使其更接近于正常的代码流。无论哪种方式,协程代码都无法与同步代码结合,并且 runBlocking 被认为是不好的做法。

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class MyViews {
    private val apis = Apis()
    
    fun onViewCreate() {
        // Using example of launch -- cannot return value
        // This code will split off from the sync flow, and we cannot guarantee when any of it is ran, except the order it will be run in
        CoroutineScope(Dispatchers.IO).launch {
            // One method to elevate values out of a coroutine would be callbacks
                callApisWithCallbacks { data -> 
                    processApiData(data)
                }
        }
        
        // Internally this utilizes withContext to resolve a value that is ready to be used 
        callApisWithReturn()
        
        // Continue normal work flow here
    }
    
    fun processApiData(age: Int) {
        // Do work here
        println("Current users age: $age")
    }

    fun callApisWithReturn() {
        // Use launch to get into coroutine from sync code
        CoroutineScope(Dispatchers.Default).launch {
            // withContext will return a value and can be used as if inline
            val userAge = withContext(Dispatchers.IO) { apis.getUserAge() }
            processApiData(userAge)
        } 
        
        // Suspend function cant be called outside of coroutine
        // apis.getUserAge()
    }

    suspend fun callApisWithCallbacks(cb: (Int) -> Unit) {
        val age = apis.getUserAge()
        cb(age)
    }
}

class Apis {

    suspend fun getUserAge(): Int {
        // Simulate delay from API
        delay(1000)

        return 5
    }
}