封装Kotlin协程请求,这一篇就够了
协程(coroutines)的封装
在默认的Kotlin协程环境中,我们需要自定义协程的作用域CoroutineScope,还有负责维护协程的调度等等,有没有方法可以让协程的使用者屏蔽对底层协程的认识,简单就能使用呢?这里带来了一个封装思路。(这里没有考虑生命周期相关的封装,如果需要实际落地可以在deferred里面封装),这里有个背景,比如在java kotlin混合开发的时候,如果java同学不会kotlin,就需要更上一层的抽象了
封装前例子
假如我们有个一个suspend函数
suspend fun getTest():String{
delay(5000)
return "11"
}
我们要实现的封装是:
1.执行suspend函数,并且使用者对底层无感知,无需了解协程就可以使用,这就要求我们屏蔽CoroutineScope细节
2.自动类型转换,比如返回String我们就应该可以在成功的回调中自动转型为String
3.成功的回调,失败的回调等
4.要不,来个DSL风格
//
async{
// 请求
getTest()
}.await(onSuccess = {
//成功时回调,并且具有返回的类型
Log.i("print",it)
},onError = {
},onComplete = {
})
可以看到,编译时就已经将it变为我们想要的类型了!
我们最终想要实现上面这种方式
封装开始
思路:我们自动对请求进行线程切换,使用Dispatchers即可,还有就是我们需要有监听的回调和DSL写法,所以就可以考虑用协程的async方式发起一个请求,返回值是Deferred类型,我们就可以使用扩展函数实现.await的形式!如果熟悉flutter的同学看的话,是不是很像我们的dio请求方式呢!下面是代码,可以根据更细节的需求进行补充噢:
fun <T> async(loader:suspend () ->T): Deferred<T> {
val deferred = CoroutineScope(Dispatchers.IO).async {
loader.invoke()
}
return deferred
}
fun <T> Deferred<T>.await(onSuccess:(T)->Unit,onError:(e:Exception)->Unit,onComplete:(()->Unit)?=null){
CoroutineScope(Dispatchers.Main).launch {
try{
val result = this@await.await()
onSuccess(result)
}catch (e:Exception){
onError(e)
}
finally {
onComplete?.invoke()
}
}
}
总结
是不是非常好玩呢!我们实现了一个dio风格的请求,对于开发者来说,只需定义suspend修饰的函数,就可以无缝使用我们的请求框架!
作者:Pika
链接:https://juejin.cn/post/7100856445905666079
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
链接:https://juejin.cn/post/7100856445905666079
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。