何时使用Kotlin suspend关键字?

何时使用Kotlin suspend关键字?,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,我可以完成这项工作,而无需挂起,它甚至使测试更容易(可以在不添加运行阻塞的情况下进行测试) 我的问题是: asyncFunc1vsasyncFunc2,哪个更好,为什么 如果asyncFunc2更好,我是否应该在协同程序中运行函数时始终使用suspend 更新 在Kotlin协程的最新版本中,我注意到如果一个方法不包含任何协程代码(比如launch,async,等等),编译器抱怨如果在中没有调用其他挂起函数,则此检查会将挂起修饰符报告为冗余。因此,我假设挂起仅应在必须时使用 更新2 来自: 挂起

我可以完成这项工作,而无需
挂起
,它甚至使测试更容易(可以在不添加
运行阻塞
的情况下进行测试)

我的问题是:

  • asyncFunc1
    vs
    asyncFunc2
    ,哪个更好,为什么
  • 如果
    asyncFunc2
    更好,我是否应该在协同程序中运行函数时始终使用
    suspend
  • 更新 在Kotlin协程的最新版本中,我注意到如果一个方法不包含任何协程代码(比如
    launch
    async
    ,等等),编译器抱怨
    如果在
    中没有调用其他挂起函数,则此检查会将挂起修饰符报告为冗余。因此,我假设
    挂起
    仅应在必须时使用

    更新2

    来自:

    挂起函数可以像普通函数一样在协同路由中使用,但它们的附加特性是,它们可以反过来使用其他挂起函数(如本例中的delay)来挂起协同路由的执行


    suspend
    关键字表示可以暂停协同程序以供以后执行

    话虽如此,您应该有意识地将其用于将被挂起的协同路由(例如,您的
    asyncFunc2()
    发出了一个HTTP调用,正在等待响应以处理它)

    所以

  • 对于将以某种方式延迟的函数(等待一些计算、api响应等),请使用
    suspend
  • suspend-fun
    只能从协同程序运行。因此,如果它被挂起,它将阻止协同程序。去掉
    suspend
    关键字,但在协同程序中运行它,它将具有相同的效果。但是,如果您从协同程序外部运行此函数,它将阻止它正在运行的线程
  • 测试协同路由时,应始终调用
    runBlocking
    。如果不调用,则挂起的协同路由可能无法完成,从而导致测试失败

  • 视情况而定。此时请参阅其他两个答案的组合:从协同程序调用任一函数的效果是相同的。但是,使用
    suspend
    关键字,函数本身可以调用其他挂起函数。使用关键字可能表示某些工作需要时间,因此可能需要uspend呼叫协同程序
  • 始终从协同程序调用的函数不需要始终具有
    suspend
    关键字。它只需要该关键字,原因如下1所示。反之亦然:只能从协同程序调用挂起函数

  • 如果需要的话,你应该只声明你的函数
    suspend
    。我会说,如果有疑问,如果编译器没有强迫你,不要使用
    suspend

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

    请注意,声明函数
    suspend
    不会使调用者在函数未挂起时做更多的事情。如果有的话,就是限制了函数的使用


    我认为函数挂起而不必强制挂起的一个用例是,您确实绝对希望向世界表明您的函数计算量很大,从而迫使调用方处理挂起问题。

    使用suspend关键字:

    • 将以某种方式延迟的函数(等待一些计算、网络请求)

      • 每当函数调用其他挂起函数时
      • 调用withContext()的函数–withContext()是来自协同程序库的挂起函数
    经验法则是,除非被迫,否则不要将函数标记为挂起

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