• $Kotlin
    2022-02-16
    public interface Continuation<in T> { /** * The context of the coroutine that corresponds to this continuation. */ public val context: CoroutineContext /** * Resumes the execution of the corresponding coroutine passing a successful or failed [result] as the * return value of the last suspension point. */ public fun resumeWith(result: Result<T>) } suspend函数的入参Continuation,看源码可以知道需要有一个协程上下文CoroutineContext信息,只有在协程作用域里才能传递。

    作者回复: 很棒的答案。

    共 2 条评论
    18
  • Airsaid
    2022-02-28
    老师您好,为什么 Kotlin 选择使用关键字来定义挂起函数而不是使用注解呢?(例如 Compose 就使用的是注解的方式)

    作者回复: 首先,关键字其实是更好的方案,因为它是语法级的支持,注解不是。关键字是语法的一部分,而注解只是额外标注的信息,这在编译器分析抽象语法树的时候,两者的差异是很大的。 Compose之所以使用注解,是因为Compose没有增加关键字的权限,只能通过编译器插件来实现内部逻辑。

    
    17
  • 墨方
    2022-02-16
    被调用的挂起函数需要传入一个Continuation(当然这个传入也是幕后编译做的), 没有被suspend修饰的函数是没有Continuation参数的,所以被调用的挂起函数没有办法从普通函数中获取一个Continuation。

    作者回复: 很棒的答案!

    
    14
  • colin
    2022-02-16
    挂起函数本身并不支持挂起,所以它没法在普通函数中调用,而它之所以能在挂起函数中调用,是因为挂起函数最终都是在协程中被调用,是协程提供了挂起函数运行的环境。

    作者回复: 没错,具体的运行环境,就是Continuation还有上下文环境CoroutineContext。

    共 2 条评论
    5
  • AKEI
    2022-05-15
    所以kotlin的挂起函数只是相当于让回调函数更简洁,相当于封装了线程池,并没有任何更高效的性能优化是吗?

    作者回复: 它有非阻塞的特性,另外,它还更轻量,在特定场景下是会更好的。

    
    4
  • Luckykelan
    2022-04-23
    老师您好,有个问题不太清楚 val user = getUserInfo() val friendList = getFriendList(user) val feedList = getFeedList(friendList) 这段代码和协程思维模型那张动图一起看,代码执行到getUserInfo()函数时,这个函数就被挂起了,不是应该继续执行val friendList = getFriendList(user)吗?为什么实际上在这里没有继续执行而是等待了getUserInfo()的返回呢?

    作者回复: 这里的挂起,有两层含义: 1. 一个是当前线程不会被阻塞,可以执行其他任务。 2.挂起点剩下的代码,会留到之后再执行。

    共 7 条评论
    3
  • jim
    2022-02-21
    图文说明,写的真好。

    作者回复: :)

    
    2
  • InfoQ_0880b52232bf
    2022-04-18
    关于思考题,我想可以尝试逆向思考一下,假如普通函数可以调用挂起函数,那么会出现什么情况呢? 比如:我们在main方法里可以直接调用这三个挂起函数(实际不能直接调用),我们预期的结果是同步方式实现异步请求(这也是协程的特点之一),但其实按照非阻塞挂起的特点,main方法会直接打印“main end”,无法满足我们的预期: fun main() { val userInfo = getUserInfo() val friendList = getFeedList(userInfo) val feedList = getFeedList(friendList) println("main end") } suspend fun getUserInfo(): String { withContext(Dispatchers.IO) { delay(1000L) } return "BoyCoder" } suspend fun getFriendList(user: String): String { withContext(Dispatchers.IO) { delay(1000L) } return "Tom, Jack" } suspend fun getFeedList(list: String): String { withContext(Dispatchers.IO) { delay(1000L) } return "{FeedList..}" }
    展开

    作者回复: 不错的角度,有点反证法的意思~

    
    1
  • Paul Shan
    2022-03-22
    suspend -> Continuation ->CoroutineContext + resumeWith 协程上下文才是挂起和回调的幕后黑手,😀,也就是说所有的挂起函数调用的时候最终都要依托于某个协程。

    作者回复: 可以这么理解。

    
    1
  • 的的喀喀湖
    2022-02-27
    讲的确实不错,之前看了好多文章没看懂挂起的概念,跟着这两篇文章自己走了一遍代码终于能理解了

    作者回复: 加油~

    
    1