什么时候使用 Kotlin 的 suspend 关键字?

Dew*_*eed 16 kotlin kotlin-coroutines

fun startAsyncFunc() {
  launch {
    asyncFunc1()
    asyncFunc2()
  }
}

fun asyncFunc1() { ... }
suspend fun asyncFunc2() { ... }
Run Code Online (Sandbox Code Playgroud)

我可以在没有的情况下完成工作suspend,它甚至使测试更容易(它可以在不添加runBlocking.

我的问题:

  1. asyncFunc1vs asyncFunc2,哪个更好,为什么?
  2. 如果asyncFunc2更好,我应该suspend在协程中运行函数时总是使用吗?

更新

在最近的科特林协同程序的版本中,我注意到,如果方法不包含任何协同程序代码(如launchasync等),编译器会抱怨This inspection reports a suspend modifier as redundant if no other suspend functions are called inside。所以我认为suspend应该只在必须时使用。

更新2

来自谷歌的建议

Jof*_*rey 11

您应该只suspend在需要时声明您的函数。我会说,如果有疑问,如果编译器不强迫您,请不要使用suspend.

大多数情况下,如果你有充分的理由让你的函数挂起,这意味着它正在做一些可能需要你使用挂起函数的事情,withContext这将迫使你声明你的 function suspend

请注意,声明一个函数suspend并不能让您的调用者做任何事情,而不是在您的函数未挂起时。如果有的话,你就是在限制你的函数的使用。

我相信函数被挂起而不被强制挂起的一个用例是,当你真的绝对想向世界展示你的函数计算量很大,从而迫使你的调用者处理挂起。


小智 10

suspend 关键字意味着可以暂停协程以供以后执行。

话虽如此,您应该有意识地将它们用于将被挂起的协程(例如您asyncFunc2()进行了 HTTP 调用并正在等待响应来处理它)

所以。

  1. 使用suspend用于功能将在某种程度上被延迟(等待一些计算,API响应等)
  2. suspend fun只能从协程运行。因此,如果它被挂起,它将阻塞协程。把suspend关键字去掉,但是在协程中运行,也是一样的效果。但是,如果您从协程外部运行此函数,它将阻塞运行它的线程。

在测试协程时,您应该始终调用runBlocking. 如果不这样做,被挂起的协程可能无法完成,从而导致测试失败。