gpt4 book ai didi

kotlin - 应使用 CoroutineScope 的扩展函数或挂起函数

转载 作者:行者123 更新时间:2023-12-02 13:08:48 32 4
gpt4 key购买 nike

我正在使用协程编写一个应用程序(下面的代码已大大简化)。最近看了Coroutines in Practice说话有点糊涂了。原来我不知道什么时候使用 CoroutineScope 的扩展函数,什么时候使用挂起函数。

我有一个实现了 CoroutineScope 的 mediator(Presenter/ViewModel/Controller/etc):

class UiMediator : CoroutineScope {
private val lifecycleJob: Job = Job()
override val coroutineContext = lifecycleJob + CoroutineDispatchersProvider.MAIN
// cancel parent Job somewhere

fun getChannel() {
launch {
val channel = useCase.execute()
view.show(channel)
}
}
}

业务逻辑(交互器/用例):

class UseCase {
suspend fun execute(): RssChannel = repository.getRssChannel()
}

还有一个存储库:

class Repository {
suspend fun getRssChannel(): RssChannel {
// `getAllChannels` is a suspending fun that uses `withContext(IO)`
val channels = localStore.getAllChannels()
if (channels.isNotEmpty()) {
return channels[0]
}

// `fetchChannel` is a suspending fun that uses `suspendCancellableCoroutine`
// `saveChannel` is a suspending fun that uses `withContext(IO)`
return remoteStore.fetchChannel()
.also { localStore.saveChannel(it) }
}
}

所以我有几个问题:

  1. 我是否应该将 Repository#getRssChannel 声明为 CoroutineScope 的扩展函数(因为它产生了新的暂停函数:getAllChannelsfetchChannel, saveChannel)?那么如何在 UseCase 中使用它呢?
  2. 我是否应该将 Repository#getRssChannel 包装到一个coroutineScope 函数使所有生成的暂停函数是后者的 child ?
  3. 或者也许它已经很好了,我什么都不应该改变。何时然后将函数声明为 CoroutineScope 的扩展?

最佳答案

问题 1 的答案:

不,你不应该Repository#getRssChannel声明为CoroutineScope的扩展函数,因为你只调用挂起函数而不是启动( launch/async) 新作业。正如@Francesc 解释的那样,CoroutineScope 的扩展函数应该只开始新的工作,但不能立即返回结果,不应该声明为 suspend 本身。

问题 2 的答案:

不,您应该Repository#getRssChannel 包装到CoroutineScope 中。仅当您在此方法中启动 (launch/async) 新协程时,包装才有意义。新作业将是当前作业的子作业,外部方法只会在所有并行作业完成后返回。在您的情况下,您有其他暂停协程的顺序调用,并且不需要新的范围。

问题 3 的答案:

是的,您可以保留您的代码。如果您多次需要 UiMediator#getChannel 的功能,那么此方法将是 CoroutineScope 的扩展函数的候选方法。

关于kotlin - 应使用 CoroutineScope 的扩展函数或挂起函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53770772/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com