- 深入理解Kotlin协程
- 霍丙乾
- 526字
- 2022-02-25 09:35:45
1.2.1 结果传递
不同于同步调用,由于异步调用是立即返回的,因此被调方的逻辑通常存在两种情形:
·结果尚未就绪,进入任务执行的状态,待结果就绪后通过回调传递给调用方;
·结果已经就绪,可以立即提供结果。
两种情况如图1-3所示,见代码清单1-5。
代码清单1-5 异步回调返回结果的两条路径示意
fun asyncBitmap( url: String, callback: (Bitmap) -> Unit ): Bitmap? { return when (val bitmap = Cache.get(url)) { null -> { thread { download(url) .also { Cache.put(url, it) } .also(callback) } null } else -> bitmap } }
图1-3 异步回调示意图
asyncBitmap函数的逻辑结果是Bitmap类型,如果结果已经存在,会直接将结果返回,否则返回null,通知主流程开始执行异步任务,等异步操作结束之后再通过回调来返回结果。调用它的代码见代码清单1-6。
代码清单1-6 调用异步函数asyncBitmap
val bitmap = asyncBitmap("...") { show(it) // ... ② 异步请求 } if (bitmap != null) { show(bitmap) // ... ① 直接返回 }
代码清单1-6中的序号与图1-3对应,其中①对应Nonsuspended分支,②对应Suspended分支,我们可以确保程序总是可以沿着①或者②当中的一条路径执行。
当然,通常我们不会如此设计回调API,因为这样反而让程序写起来更复杂了。更为常见的做法是,在结果就绪的情况下仍然立即以回调的形式传递给调用方,以保证结果传递方式的透明性。
不过,如果能够借助编译器的手段来简化这段逻辑的编写,本节提供的这个思路会非常有用。
提示 Kotlin协程的挂起函数(suspend function)本质上就采取了这个异步返回值的设计思路,详情见3.2.3节。