请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于suspandLambda的相关问题

图片描述
在我的理解中it应该指的是startCoroutine传进去的那个continuation,跟这个所谓的suspendLambda和SafeContinuation感觉没什么关系啊,不知道是不是我的理解有问题

正在回答 回答被采纳积分+3

1回答

bennyhuo 2020-03-20 07:38:22

这里的 it 不是 start的时候传进去的。传进去的那个 continuation(也就是 completion) 只有在协程体执行完成之后才会回调,而且回调也不是由我们自己写出了的。


协程体编译之后会生成一个 SuspendLambda 的类的对象,这个 it 就是这个对象被 SafeContinuation(以及后面要讲到的 拦截器)包装之后的结果。

对 completion 的调用实际上是在 SuspendLambda 当中定义的。这块儿如果还是不明白,可以看下 11-6 6:40 左右用 Java 代码模拟协程执行的例子,相关源码在这里:

https://git.imooc.com/coding-398/Kotlin-Tutorials/src/master/CoroutineBasics/src/main/java/com/bennyhuo/kotlin/coroutinebasics/javaimpl/ContinuationImpl.java

0 回复 有任何疑惑可以回复我~
  • 这个it应该不是被包装SafeContinuation吧,我看源码里,startCoroutine其实就是下面这段代码
    createCoroutineUnchecked(completion).resume(Unit)
    然后createCoroutine的文档说了这个SafeContinuation的resume只能被invoke一次:
    /**
     * Creates a coroutine without receiver and with result type [T].
     * This function creates a new, fresh instance of suspendable computation every time it is invoked.
     * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
     * The [completion] continuation is invoked when coroutine completes with result or exception.
     * Repeated invocation of any resume function on the resulting continuation produces [IllegalStateException].
     */
    上面的代码文档说了resume只在我们启动创建的携程(也就这个SafeContinuation)使invoke。之后的resume invoke会抛出异常, IllegalStateException. 这个例子里面startCoroutine已经invoke了resume,如果再在a里面resume应该会抛出异常。
    
    然后我又跑去看了Roman在kotlinConf上的deep dive into coroutine talk,这个it其实应该是指传进a里的那个state machine (其实也是一个continuation的实现),编译器在suspen lamba开头隐式生成的。
    回复 有任何疑惑可以回复我~ 2020-06-21 08:45:43
  • Roman的实现伪代码:
    fun postItem(item: Item, cont: Continuation) {
      val sm = cont as? ThisSM ?: object : ThisSM {
        fun resume(...) {
          postItem(null, this)
        } 
      }
      switch (sm.label) {
        case 0:
          sm.item = item sm.label = 1 requestToken(sm)
        case 1:
          createPost(token, item, sm)
        ...
      }
    }
    如果把postItem想象成我们这里的suspend lambda,那postItem的cont就是completion,把createPost想象成a的话,那a的it就是那个隐式生成的sm.
    不知道我理解的对不对
    回复 有任何疑惑可以回复我~ 2020-06-21 08:49:16
  • bennyhuo 回复 aiqingyuyan #3
    问题截图里面的这个 it 是 suspendCoroutine 函数包装过的,源码一看就看到了,跟你说的不冲突。这个东西包装的就是用于启动协程的 Lambda 生成的状态机。
    回复 有任何疑惑可以回复我~ 2020-06-21 09:07:44
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信