kotlin - 为每个函数指定 Kotlin 协程上下文还是将其留给调用者函数?推荐哪一款?

标签 kotlin kotlin-coroutines

我是 Android 开发领域的 Kotlin 新手,我想知道在使用 Coroutine 时建议使用以下哪种方法?

1。在每个函数声明处指定协程上下文

在这种方法中,每个函数都会将调用者上下文覆盖为适当的上下文。

我的假设:好处是调用者函数不需要了解它所调用的函数的内部。

suspend fun callee() = withContext(Dispatchers.IO) {
    httpClient.get("https://google.com")
}

suspend fun caller() {
    callee()
    callee()
}

2。委托(delegate)为调用者选择正确的上下文

在这里,我们将决定权留给调用者函数,这意味着它可以选择适合该用例的任何上下文。

请挑战:这降低了代码复杂性和上下文切换的开销。

suspend fun callee() {
    httpClient.get("https://google.com")
}

suspend fun caller() {
    // Specify context only once
    withContext(Dispatchers.Main) {
        callee()
        callee()
    }
}

2.5。图书馆已经解决了这个问题!

由于我使用 KTOR 客户端,我可以假设该库已经选择了正确的上下文并且我不需要指定它们吗?

suspend fun callee() {
    // Assumption: Ktor will run the request in correct context
    httpClient.get("https://google.com")
}

suspend fun caller() {
    callee()
    callee()
}

最佳答案

  1. 和2.5。根据设计,挂起函数必须永远不会阻塞线程。这意味着两件事:
  • 我们可以直接从任何其他挂起函数调用它们。我们不需要切换调度程序来调用挂起函数。
  • 如果需要,这些功能必须正确切换到另一个调度程序。或者在内部使用异步处理。

如果您看到一个挂起函数阻塞了线程或期望在特定线程中调用,则说明该函数的实现不正确。

当然,在类内实现内部私有(private)功能时,我们有时可以忽略这些规则。也许我们想例如将执行 I/O 的较大代码块拆分为多个较小的函数,但我们仍然需要它们可挂起。在这种情况下,仅在入口点切换到 Dispatchers.IO 一次可能是有意义的。

关于kotlin - 为每个函数指定 Kotlin 协程上下文还是将其留给调用者函数?推荐哪一款?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77378763/

相关文章:

Gradle 上的 Android 应用程序 : Unable to merge dex

generics - 复制 Kotlin 数组减去特定索引处的元素

java - Kotlin:从 Java 类访问公共(public)字段,该类也覆盖同名的公共(public) getter

android - 如何在Android中命名协程?

kotlin - 挂起函数引用作为 let 的参数会出现错误

android - 单元测试协程 runBlockingTest : This job has not completed yet

kotlin - 如何在特定点挂起协程

android - 返回结果和 lateinit : property executions has not been initialized

android - Kotlinx 从错误的布局中注入(inject) View

java - 在 Kotlin 上转换泛型类型