挂起函数

挂起在我们调用使用suspend修饰的函数时发生:

suspend fun doSomething(foo: Foo): Bar {
    ...
}

这样的函数被称为挂起函数,因为调用这样的函数可能会挂起协同程序(假如调用的结果显示其已经可用,库可以决定不挂起来继续处理)。挂起函数可以有参数和返回值,但是它们只能在协同程序或其他挂起函数中调用。事实上,要启动一个协同程序至少需要一个挂起函数,这个函数经常是匿名的(挂起lambda表达式)。下面来看看标准库中的异步实现:

fun <T> async(block: suspend () -> T)

在这里,async()函数是一个正常的函数(不是挂起函数),但是block参数是一个函数类型并且使用了suspend修饰符:suspend () -> T。因此当我们传递一个lambda表达式给async()函数时,其实是一个挂起lambda表达式,并且我们可以从中调用挂起函数:

async {
    doSomething(foo)
    ...
}

继续类比,await()函数可以是一个挂起函数,这个函数会挂起直到一些计算完成之后返回结果。

async {
    ...
    val result = computation.await()
    ...
}

更多的关于async/await函数信息请查看kotlinx.coroutines

需要注意的是挂起函数await()和doSomething()不能在正常函数中调用,比如main()函数:

fun main(args: Array<String>) {
    doSomething() // ERROR: Suspending function called from a non-coroutine context
}

同时需要注意的是挂起函数可以是虚函数,当覆写它们的时候,需要显示指定suspend修饰符。

interface Base {
    suspend fun foo()
}
class Derived: Base {
    override suspend fun foo() { ... }
}

results matching ""

    No results matching ""