使用协成将异步转同步
文章目录
- 1.普通的异步写法
- 2.使用协成改写
- 3.多线程并发
最近学习了一下kotlin的协成,发现使用协成能够帮助我们将异步代码转换成同步代码,能够极大的提高代码的可读性。
1.普通的异步写法
如下所示,为我们常见的一些异步代码,通常情况下,我们会传递一个callback到方法里面,等到异步代码执行完毕之后回调回来。
public fun realRequest(response: Callback) {Thread(Runnable {println("start request:" + address)Thread.sleep(1000)if (address.equals("failed")) {response.onError(0, "address failed")} else {response.onResult("success:" + address)}}).start()
}
我们调用这段代码如下
Request("test").realRequest(object: Callback {override fun onResult(result: String) {println("success!")}override fun onError(errorCode: Int, errorMsg: String) {println("errorcode:${errorCode},errorMsg:${errorMsg}")}})
我们从这段代码里面可以看出,Request(“test”)前后的代码和回调方法里面的代码割裂开了,增加了阅读成本,另外如果回调方法特别长,阅读起来就会特别费劲。
那么我们可以尝试着用协成的方法来改写这段代码。
2.使用协成改写
我们可以在Request类里面增加一个suspend方法,将realRuest转变成同步方法,具体如下
class Request(val address:String) {//增加suspend方法public suspend fun request(): TestResult {return suspendCoroutine { continuation ->realRequest(object : Callback {override fun onResult(result: String) {continuation.resume(TestResult(true,result))}override fun onError(errorCode: Int, errorMsg: String) {continuation.resume(TestResult(false,errorMsg,errorCode))}})}}public fun realRequest(response: Callback) {Thread(Runnable {println("start request:" + address)Thread.sleep(1000)if (address.equals("failed")) {response.onError(0, "address failed")} else {response.onResult("success:" + address)}}).start()}
}
具体使用如下,在协成当中访问就可以了
GlobalScope.launch {val result = Request("test").request()println(result.toString())
}
如果我们引用的是一个库,不方便更改Request源码,那么也可以使用扩展的方式来实现,
如下所示,我们在Request外部给其增加了一个扩展方法outRequest
suspend fun Request.outRequest():TestResult{return suspendCoroutine { continuation ->this.realRequest(object :Callback{override fun onResult(result: String) {continuation.resume(TestResult(true,result))}override fun onError(errorCode: Int, errorMsg: String) {continuation.resume(TestResult(false,errorMsg,errorCode))}})}
}
使用方式也是完全一致
GlobalScope.launch {val result = Request("outTest").outRequest()println(result.toString())
}
3.多线程并发
如果我们想要发起多个请求,可以使用flow。
GlobalScope.launch {val start = System.currentTimeMillis()val r1 = Request("test1")val r2 = Request("test2")val r3 = Request("test3")val list = listOf(r1,r2,r3)flow {for (request in list) {val result = request.request()emit(result)}}.collect {println(it.toString())}val gap = System.currentTimeMillis() - startprintln("cost time:"+gap)
}
如上面代码所示,我们有三个异步请求,可以将其放到flow当中,分别进行emit,然后在collect当中获取结果。
每个异步任务执行时间是1秒,从结果当中可以发现,整体执行时间为3秒,可以看出所有的任务都是串行执行。
如果我们希望任务能够并发执行呢,可以使用channelFlow
GlobalScope.launch {val start = System.currentTimeMillis()val r1 = Request("test1")val r2 = Request("test2")val r3 = Request("test3")val list = listOf(r1,r2,r3)channelFlow {for (request in list){async {val result = request.request()send(result)}}}.collect {println(it.toString())}val gap = System.currentTimeMillis() - startprintln("cost time:"+gap)
}
从执行结果可以看出,任务为并发执行
使用协成将异步转同步相关推荐
- pyhon——进程线程、与协程基础概述(同步异步)
一直以来写博客都是实用主义者,只写用法,没信心写原理,但是每一次写作业的过程都有一种掘地三尺的感觉,终于,写博客困难症重症患者经历了漫长的思想斗争,还是决定把从网上淘到的各种杂货和自己的总结放在一起, ...
- python协成_Python协程技术的演进
引言 1.1. 存储器山 存储器山是 Randal Bryant 在<深入理解计算机系统>一书中提出的概念. 基于成本.效率的考量,计算机存储器被设计成多级金字塔结构,塔顶是速度最快.成本 ...
- python中协程与函数的区别_python协程和异步IO
1.并发.并行.同步.异步.阻塞.非阻塞 并发:是指在同一个时间段内,有几个程序都处于启动运行到运行结束之间 并行:在同一个时间点上,有几个程序同时运行 同步:当一个同步操作发出去后,调用者一直等待返 ...
- python协程和异步编程
文章目录 协程 & 异步编程(asyncio) 1. 协程的实现 1.1 greenlet 1.2 yield 1.3 asyncio 1.4 async & awit 1.5 小结 ...
- Python 彻底解读协程与异步【看完包会】
title: Python 协程与异步 copyright: true top: 0 date: 2018-08-11 10:15:50 tags: categories: Python进阶笔记 pe ...
- Java 异步与同步的区别
同步: 所有操作完成之后,才会通知用户操作完成了. 异步:不用等所有操作完成之后,就会通知用户操作完成了,然后后台会继续操作直到完成结束. 为了方便理解 举例个常见的 android 网络请求使用的异 ...
- python 协程和异步的关系_python协程与异步协程
在前面几个博客中我们一一对应解决了消费者消费的速度跟不上生产者,浪费我们大量的时间去等待的问题,在这里,针对业务逻辑比较耗时间的问题,我们还有除了多进程之外更优的解决方式,那就是协程和异步协程.在引入 ...
- Node.js模拟发起http请求从异步转同步的5种方法
使用Node.js模拟发起http请求很常用的,但是由于Node模块(原生和第三方库)提供里面的方法都是异步,对于很多场景下应用很麻烦,不如同步来的方便.下面总结了几个常见的库API从异步转同步的几种 ...
- [ JS 进阶 ] Ajax 详解 (2) :XHR 实例 GET 和 POST 异步和同步
上一篇文章 我们大概知道了XHR对象是什么东东,也都了解了它的一些属性和方法,那么现在具体来实现一下Ajax技术 和 了解下XHR2对象. 1.实现Ajax 先来创建个XHR对象的实例: var xh ...
- 路由器的异步和同步串行接口
本文以Cisco路由器为例,介绍了路由器上常用接口的类型.特点和应用场合. 1 EIA/TIA 232 EIA/TIA 232有时又被称作RS-232 C.RS(Recommended Standa ...
最新文章
- python画饼图-python使用Matplotlib画饼图
- 第三次学JAVA再学不好就吃翔(part50)--String类练习
- android studio放置在函数上面看_像写Flutter一样开发Android原生应用
- Modularity(模块化-CMD规范)
- 内存的工作原里(二)
- Sharepoint-拾贝
- 写项目文档比写代码难多了
- Opencv笔记(二十一)——傅里叶变换
- 手机计算机软件删除了怎么恢复,手机卸载的软件怎么恢复?手机卸载的软件恢复方法介绍...
- 计算机科学ppt模板,计算机科学与技术ppt模板
- 实战分享:大学生兼职赚钱创业,财务自由,顺势布局
- 网络数据传输的节点大全
- 【无标题】c语言指针2333
- android sensor hal,Android Sensor详解(3)porting drvier
- 微信网页中点击图片放大
- Java HashMap的遍历(常用的四种方式),及key,value规律
- 借助小程序·云开发制作校园导览小程序丨实战
- 链路追踪google dapper论文 中文
- js中向对象添加键值对, 如 var data={1:'a' } ,添加 { 2:'b' }
- win10下安装win7双系统