其他分享
首页 > 其他分享> > 【Kotlin suspend coroutines 原理,代码转为状态机,粗略笔记】

【Kotlin suspend coroutines 原理,代码转为状态机,粗略笔记】

作者:互联网

结论

先说结论 感想,状态机转变 在最后面。

如视频所说,没有magic。类比于用 中文写程序,中文是宏命令啥的。(个人臆测)

我了解的点

  1. compiler帮你用 回调书写异步代码
  2. compiler将你的code,翻译成状态机,来运行、暂停你的代码 。
  3. 相当于用关键字 suspend、await 告诉compiler,我代码怎么拆分。然后compiler跟你拆成 一段一段的代码,来执行。

不足:

  1. 没 涉及 coroutines是如何调度的,具体啥线程。VM 的领域知识了吧。

推测

感想

这尼玛确实不用深入理解,因为你Thread杂跑异步的,你不也没去理解嘛。。。。。。
这就是新手为啥好掌握吧,没有理解包袱。

资料

文章翻译的Google视频,本人也是听了个大概,故本文仅 抛砖引玉,难以深度解惑,诸君如有需要 还需自行看视频。 当然,各位如有指导、资料,更是期望不吝赐教,多谢。

YouTube视频地址,需用梯子

笔记

你写的源码,为direct call,没有callback。但Compiler 会给你生成Callback,就这么简单。。。。。。。。

Compiler 转变的大致步骤:

//direct call
suspend fun postItem(item: Item) {
	//suspend action
	val token = requestToken()
	
	//Continuation
	val post = createPost(token, item)
	procsessPost(post)
}

//indirect call CPS
fun postItem(item: Item) {
	requestToken { token ->
		createPost(token, item) { post ->
			processPost(post)
		}
	}
}
//direct call
suspend fun postItem(item: Item) {
	//Label 0 
	val token = requestToken()
	//Label 1 
  val post = createPost(token, item)
	//Label 2 
	procsessPost(post)
}

//direct call
suspend fun postItem(item: Item) {
	switch (label) {
		case 0:
			val token = requestToken()
		case 1:
			val post = createPost(token, item)
		case 2:
			porcessPost(post)
	}
}

// Save state
suspend fun postItem(item: Item, cont: Continuation) {
	val sm = object: CoroutineImpl {...}
	switch (sm.label) {
		case 0:
			//val token = requestToken(sm)
			sm.item = item
			sm.label = 1
			requestToken(sm)
		case 1:
			val post = createPost(token, item, sm)
		case 2:
			porcessPost(post)
	}
}

Compiler生成了一个Continuation,并添加到方法的形参中。而这个interface就是callback的抽象,并由Compiler根据 suspend等 关键字,抽取实际代码

interface Continuation<T> {
	val context: CorotineContext
  fun resume(value: T)
  fun resumeWithException(exception: Throwable)
}

// generate Callback
suspend fun postItem(item: Item, cont: Continuation) {
	val sm = object: CoroutineImpl {
		fun resume() {
			postItem(null, this)
		}
	}
	switch (sm.label) {
		case 0:
			//val token = requestToken(sm)
			sm.item = item
			sm.label = 1
			requestToken(sm)
		case 1
			val item = sm.item
			val token = sm.result as Token
			sm.label = 2
			val post = createPost(token, item, sm)
	}
}

State Machine vs Callbacks

//State Machine
suspend fun postItem(item: Item) {
	val token = requestToken()
	val post = createPost(token, item)
	procsessPost(post)
}

//Callbacks
fun postItem(item: Item) {
	requestToken { token ->
		createPost(token, item) { post ->
			processPost(post)
		}
	}
}
  1. StateMachine分配类少
    StateMachine:重用closure / state object (即对应Item)
    Callback: 每次调用suspend function,都需要create new object (即对应的callback实参))

  2. 便于 处理N个异步请求

//State Machine
suspend fun postItem(items: Item) {
	 for (item in items) {
		val token = requestToken()
		val post = createPost(token, item)
		procsessPost(post) 
	 }

}

//Callbacks
fun postItem(item: Item) {
	// 回调地狱
	requestToken { token ->
		createPost(token, item) { post ->
			processPost(post)
				requestToken { token ->
					createPost(token, item) { post ->
						processPost(post)
						//....
					}
				}
		}
	}
}

标签:suspend,val,Kotlin,状态机,item,token,sm,post
来源: https://blog.csdn.net/zhjali123/article/details/114436674