suspend 是kotlin中用于对协程中的挂起函数的标注关键字,在使用suspend函数的时候,会有一些疑问,在此做一些记录,其中包含了一些个人理解,如有错误,欢迎在评论区指出
疑问一:协程内的函数方法都需要用suspend来修饰吗
回答:协程内部的函数并不是都需要用suspend来修饰 一但一个函数使用了suspend来修饰,则代表该函数具备协程的挂起和恢复能力 那什么场景下需要挂起恢复,或者换种问法,什么时候需要suspend来进行修饰呢 这边有个很常见的场景,就是该方法中需要进行线程切换,使用一个新的线程来处理一个耗时的业务逻辑 并且在耗时任务完成后会切回到协程所在的线程进行下一步的处理,这个时候就需要将协程挂起,等任务完成后再通知协程进行恢复 ,因此这种场景下是需要用suspend进行修饰的
当然以上只是诸多场景中最常见的一种,其他场景此处不再赘述
疑问二:为什么suspend关键字有的时候会被IDE至灰
IDE工具具备比较基础的代码静态检测能力,IDE将suspend关键字至灰,说明IDE识别到该方法并不具备挂起恢复能力
需要注意的是IDE的检测手段是判断suspend方法的内部有没有其他suspend方法,如果内部不包含其他suspend方法,就会认为该方法不具备挂起恢复能力
疑问三:suspend关键字有什么具体作用
通过编写一个最简单的suspend方法进行反编译,发现编译器给每个suspend修饰的方法都传入了一个Continuation
Continuation正是用来将挂起状态进行恢复的接口,这就跟问题一可以呼应起来,也就是说使用suspend修饰后的函数,具备了挂起和恢复协程状态的基本接口,只有具备这种基本接口,才能被框架操作,实现挂起恢复的功能,大家注意一下我的说法,是当方法体适配了接口,框架来实现挂起恢复,而不是被这个关键字修饰之后,方法具备挂起恢复能力
suspend fun suspendSleep() {
xxxxxx
}
反编译后
public final Object suspendSleep(@NotNull Continuation $completion) {
xxxxxx
return Unit.INSTANCE;
}