java - kotlin 协程是如何在底层实现的?
问题描述
Kotlin 协程是该语言的关键特性之一。我很好奇他们是如何实现的。所以我写了这个 kotlin 代码片段,
CoroutineScope(Dispatchers.IO).launch {
someFun(6) // A suspend fun with single int argument.
} // Which is converted into a synthetic method with an extra argument of continuation type added at the end.
然后将其编译为字节码,然后将其反编译为 Java(在 Android Studio 中)。我懂了,
BuildersKt.launch$default(CoroutineScopeKt.CoroutineScope((CoroutineContext)Dispatchers.getIO()), (CoroutineContext)null, (CoroutineStart)null, (Function2)(new Function2((Continuation)null) {
private CoroutineScope p$;
Object L$0;
int label;
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
Object var3 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
CoroutineScope $this$launch;
switch(this.label) {
case 0:
ResultKt.throwOnFailure($result);
$this$launch = this.p$;
MainActivity var10000 = MainActivity.this;
this.L$0 = $this$launch;
this.label = 1;
if (var10000.someFun(6, this) == var3) {
return var3;
}
break;
case 1:
$this$launch = (CoroutineScope)this.L$0;
ResultKt.throwOnFailure($result);
break;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
return Unit.INSTANCE;
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
Function2 var3 = new <anonymous constructor>(completion);
var3.p$ = (CoroutineScope)value;
return var3;
}
public final Object invoke(Object var1, Object var2) {
return ((<undefinedtype>)this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
}), 3, (Object)null);
我理解了这段代码的某些部分。但仍有一些部分没有进入我的脑海。
根据这个invokeSuspend
答案,一个挂起函数在每个挂起点被拆分为多个延续,然后通过连续调用从头开始执行。每次invokeSuspend
调用 when 时,都会执行相应的 switch case,然后更新lable
. 所以下次当invokeSuspend
被调用时,它会运行下一个案例。当 <it?> 被调用挂起函数时,它停止调用invokeSuspend
并等待恢复调用。一旦它被调用恢复,它再次正常继续。这就是我所知道的。
在第一行,Function2 构造函数为 Continuation 接受一个空对象。但是为什么Function2
类只有一个参数构造函数呢?我不知道Function2的实现。我搜索了它的源代码,但没有得到它。如果可能的话,我想要一个指向源代码的链接kotlin.jvm.functions.Function2
。
在 case0: 的末尾,if (var10000.someFun(6, this) == var3) return var3;
实际上是什么意思。
在上一次调用 invokeSuspend 完成后,谁负责调用 invokeSuspend。以及它如何知道最后一个 invokeSuspend 案例何时执行?
3, (Object)null
最后一个参数代表什么launch$default
解决方案
推荐阅读
- r - networkd3 正在显示所有数据,而不是我想根据 Shiny 应用程序中的小部件输入显示的子集
- sas - SAS 是低于目前列中最高数字的数字
- javascript - 实时时间到达 23:00 时的 Javascript
- sql - 如果为空,则将 NVL 与 JOIN 一起使用不返回默认值
- vimeo - 如何在 Vimeo 点播页面中管理多个季节?
- angular - 将查询参数传递给辅助路由 Angular 5
- html - bootstrap4 中的多个模式不起作用
- javascript - Mongoose - 如果新值不在可用枚举列表中,如何设置默认值
- python - Pandas 根据字典中描述的关系加入两个数据框
- typescript - 结构类型和用户定义的类型保护