库中的基本协程网络调用

问题描述 投票:3回答:2

我正在阅读和学习Kotlin中的协同程序,以便在小型库中用于娱乐/学习目的。在文档中,您可以执行类似的操作

GlobalScope.launch {

}

所以在我的方法中,

fun myMethod() {
    GlobalScope.launch {
        // do some networking code
    }   
}

使用GlobalScope为库启动协程是最佳做法吗?在文档中说

应用程序代码通常应该使用应用程序定义的CoroutineScope,非常不鼓励使用异步或在GlobalScope实例上启动。

这显然是一个库,不一定是应用程序代码。但我不确定这是否是与协同程序在后台进行联网的最佳方式。

我也试过了

runBlocking {
    async {
        // do some networking code
    }
}

认为runBlocking引入了一个新的协程范围,但我认为在这种情况下它继承了它的父节点作为主线程的范围,所以我得到一个关于主UI线程没有网络的例外。

kotlin
2个回答
3
投票

您可以创建一个挂起函数,这将强制用户从协程本身调用它。如果您的方法使用withContext,则不必担心GlobalScope或配置范围。 withContext只是告诉协程使用哪个上下文(对于网络,你需要IO。而且范围现在由用户启动它来确定。

我构建你的方法的方式是:

suspend fun myMethod() = withContext(Dispatchers.IO) {
    // do some networking code
}

1
投票

根据您要实现的目标,您甚至可以在库中使用不同的模式。

如果你的函数应该在启动一些协同程序后立即返回,那么“最佳实践”是将你的函数声明为CoroutineScope的扩展,这样你就不必使用全局作用域:

fun CoroutineScope.launchesAndReturnsImmediately() {
    // launch can be called because we are extending CoroutineScope
    launch {
        // some work
    }
}

话虽如此,您通常不需要在库中立即返回,因此您可以声明您的函数suspend,这在消费者方面更容易掌握。那里有多种选择:

  • 通过使用withContext在适当的线程池上运行,或调用其他挂起函数,在后台进行一些工作
  • 使用coroutineScope启动子协同程序并分解工作,但仍然暂停,直到所有子协程都完成
  • 通过使用suspendCoroutinesuspendCancellableCoroutine包装基于回调的异步代码来“创建”暂停
© www.soinside.com 2019 - 2024. All rights reserved.