- 深入理解Kotlin协程
- 霍丙乾
- 769字
- 2022-02-25 09:35:47
1.3.5 Kotlin协程
Kotlin协程(Coroutines)也是为异步程序设计而生的。有人称它只是一个“线程框架”,认为Kotlin协程就是用来切换线程的,这显然有些“一叶障目,不见泰山”了。
Kotlin协程的设计很巧妙,它只用了一个关键字suspend来表示挂起点,包含了异步调用和回调两层含义。我们前面提到,所有异步回调对于当前调用流程来讲都是一个挂起点,在这个挂起点我们可以做的事情非常多,既可以像async/await那样异步回调,又可以添加调度器来处理线程切换,还可以作为协程取消响应的位置,等等。
我们先来看一个Kotlin协程处理异步调用的例子,见代码清单1-23。
代码清单1-23 使用Kotlin协程
suspend fun bitmapSuspendable(url: String): Bitmap = suspendCoroutine<Bitmap> { continuation -> thread { try { continuation.resume(download(url)) } catch (e: Exception) { continuation.resumeWithException(e) } } }
被suspend关键字修饰的函数叫作挂起函数(suspend function),类似我们前面提到的被async修饰的函数,表示该函数支持同步化的异步调用。
我们使用标准库API suspendCoroutine<T>函数的返回值类型作为挂起函数bitmap-Suspendable的返回值类型,也就是泛型参数T的实参Bitmap。这个函数除了确定返回值类型外,还能够帮我们拿到一个Continuation的实例,负责保存和恢复挂起状态,逻辑效果上类似于Promise,其中几个函数意义如下。
·resume:类似于Promise的resolve,将正常的结果返回,它的参数实际上就是bitmapSuspendable的返回值Bitmap。
·resumeWithException:类似于Promise的reject,将异常返回,它的参数实际上就是bitmapSuspendable调用时会抛出的异常。
调用时,所有的挂起函数必须在其他挂起函数(或者协程体)中调用,这就好像await只能在async当中使用一样,如代码清单1-24所示。
代码清单1-24 调用Kotlin的挂起函数
suspend fun main() { try { val bitmap = bitmapSuspendable("...") ... //省略图片处理 } catch (e: Exception) { ...//省略异常处理 } }
调用时,挂起函数就相当于await之后的结果,因此大家可以看到,suspend这个关键字可以说是“分饰两角”:声明函数类型时充当async的作用,调用时充当await的作用。
这里我们仅仅对Kotlin协程进行简单介绍,目的是让大家充分了解异步程序设计的发展过程。我们将从第3章开始系统剖析Kotlin协程的实现细节和运用场景。
提示 Kotlin从1.3.0开始正式支持协程,suspend fun main作为入口函数也同时得到了支持。