目录
kotlin之协程(一),线程,进程,协程,协程可以替换线程吗?
kotlin之协程(二),Kotlin协程是什么、挂起是什么、挂起的非阻塞式
kotlin之协程(三),开始创建协程,launch,withContext
kotlin之协程(四),协程的核心关键字suspend
kotlin之协程(五),launch 函数以及协程的取消与超时
kotlin之协程(六),协程中的 async和launch的区别以及runBlocking
kotlin之协程(七),协程中relay、yield 区别
回顾
当我把 withContext 放进一个单独的函数里面
fun getImage(imageId: Int) = withContext(Dispatchers.IO) {
// IDE 报错 Suspend function'withContext' should be called only from a coroutine or another suspend funcion
}
意思是说,withContext 是一个 suspend 函数,它需要在协程或者是另一个 suspend 函数中调用。
suspend
suspend
中文意思是「暂停」或者「可挂起」
在之前我们讲到的协程的挂起,而挂起就是通过suspend来实现的
「代码执行到 suspend 函数的时候会『挂起』,并且这个『挂起』是非阻塞式的,它不会阻塞你当前的线程。」
这里面可以感受到suspend
这个关键字对于协程是多么的重要了
其实解决上面那个问题很简单,只需要在前面加一个 suspend 就能够编译通过
suspend fun getImage(imageId: Int) = withContext(Dispatchers.IO) {
...
}
那么为什么加一个suspend的关键字就可以解决这个问题,怎么做到的挂起呢?
挂起的定义
挂起的定位: 暂时切走,稍后再切回来
怎么做到挂起的
如果我们给这样的如下代码能被挂起吗?
suspend fun getImage(imageId: Int) {
...
}
答案当然是不能的,
根据挂起的定位, 暂时切走,稍后再切回来,而这段代码它不知道往哪里切啊。
所以supend关键字并不启到协程挂起/切换线程的作用
对于自定义挂起函数,需要在该函数内部直接/间接调用到某一个自带的挂起函数才行【例如withContext()】
而withcotext()也不是真的切线程的点,而是其内部的底层代码
suspend关键字到底什么作用
作用是:[提醒]
函数的创建者对函数的调用者的提醒
“我”是一个耗时的函数,我被我的创建者用挂起的方式放到了后台运行,所以要在协程里调用“我”。
它让我们的主线程不卡。通过挂起函数这种形式把耗时task切线程的这个工作交给了函数的创建者而不是调用者。
调用者只会收到一个提醒:你只需要把我放在一个协程里调用。
挂起操作靠的是挂起函数里的实际代码,而不是关键字