更优雅的使用回调函数 —— Kotlin 协程

本文介绍了如何使用Kotlin协程改造登录和连接服务的代码,避免回调地狱,提高代码可读性。通过示例展示了如何使用`suspendCoroutine`和`suspendCancellableCoroutine`改造挂起函数,并利用`async`和`await`实现并行执行。此外,还探讨了协程中`Continuation`的使用和协程被取消时的资源管理。
摘要由CSDN通过智能技术生成

简断截说,上代码!

举例:

fun login(name:String,pass:String){
	HttpMethods.webService.login(name,pass){
		 override fun onSuccess(bean: LoginBean) {
		 	connect(bean.token)
		 }
		 override fun onError(e: Exception) {
		 }
 }
fun connect(token:String){
	......//调用方法,从回调函数获取连接状态
}

上面的代码是我们比较常见的一种逻辑,发起登录请求,登录成功后使用 token 去连接其他服务,在连接成功后,继续执行其他逻辑。如果逻辑再复杂一些,比如连接失败后根据错误码去重新登录等,我们就会陷入“回调地狱”,使得代码的可读性大大降低。


就这一情况我们可以使用 Kotlin 协程来改造我们的代码:

suspend fun login(name:String,pass:String):LoginBean = suspendCancellableCoroutine { ctn->
	HttpMethods.webService.login(name,pass){
		 override fun onSuccess(bean: LoginBean) {
		 	ctn.resume(bean) //协程恢复,返回结果
		 }
		 override fun onError(e: Exception) {
		 	ctn.resumeWithException(e) //协程恢复,抛出异常
		 }
}

connect 函数的改造与 login 函数的改造思路相同,即:在获取到我们需要的数据的位置使用 continuation.resume 函数,在需要抛出异常的位置使用 continuation.resumeWithException 函数。


那么我们如何使用这两个改造完成的函数呢?代码示例如下:

launch{
	val bean = login(name,pass) //在获取结果之前,协程是挂起状态不会执行下一步
	val result = connect(bean.token) 
	
}

相比一开始的代码,此时的代码是不是看着逻辑更为清晰更为优雅。

改造普通函数变成挂起函数,最常用的两个函数是 suspendCoroutinesuspendCancellableCoroutine,这两者几乎大同小异,都是接受一个lambda表达式作为参数。区别是,前者传入的Continuation<T>,后者传入的是CancellableContinuation<T>。后者可以执行continuation.invokeOnCancellation { } 函数,该函数会在协程被取消时执行。可用于一些如资源需要关闭、或者网络请求等场景,实现在协程被取消时,关闭资源or取消网络请求。


扩展阅读+温故知新:

上面我们提到了 suspend 关键字,用于修饰挂起函数,挂起函数会将当前协程挂起(可以理解类似线程阻塞),直至continuation.resume 函数执行后才能继续执行后续代码。

这无疑会导致运行速度降低,如果我们后面的部分代码不需要挂起函数的返回值,需要实现类似并行的效果,直到我们需要挂起函数结果时才挂起当前的协程该如何操作呢?

答案是 async 函数:

launch{
	//被async函数包含,不会挂起当前协程,相当于在其他协程执行代码
	val bean = async{ login(name,pass) }
	...... //其他逻辑
	//执行至此需要上一步挂起函数的返回值时,执行await()函数
	val result = connect(bean.await().token) 
	
}

async 函数的返回值是 Deferred,该接口下的await函数是一个挂起函数。执行至此时会挂起协程,直至 async 函数内的挂起函数执行完毕获得返回值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值