注册

封装Kotlin协程请求,这一篇就够了

协程(coroutines)的封装

在默认的Kotlin协程环境中,我们需要自定义协程的作用域CoroutineScope,还有负责维护协程的调度等等,有没有方法可以让协程的使用者屏蔽对底层协程的认识,简单就能使用呢?这里带来了一个封装思路。

封装前例子

假如我们有个一个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 = {

})

df4c7852a77746a9ab3110006e77cfbc~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

可以看到,编译时就已经将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

0 个评论

要回复文章请先登录注册