全球即时:Kotlin协程-从一到多
上一篇文章,我介绍了Kotlin协程的创建,使用,协作等内容。本篇将引入更多的使用场景,继续带你走进协程世界。
使用协程处理异步数据流
常用编程语言都会内置对同一类型不同对象的数据集表示,我们通常称之为容器类。不同的容器类适用于不同的使用场景。Kotlin的Flow
就是在异步计算的需求下引入的,用于表示异步的数据流。
(相关资料图)
Flow
“问渠哪得清如许,为有源头活水来”,异步数据流的基本就是以某种方式获得异步数据。Kotlin提供了多种种方式,比较常用的就是Kotlin协程包的asFlow
扩展和flow
构造器。前者是对普通数据集的Flow
化封装,没有更多可言,我们着重来看后者。flow
构造器的主要目标就是产生一个异步数据流,它是一个泛型函数,参数是一个挂起函数,并且是FlowCollector
是扩展函数。这个接口只有一个emit
方法,就是为创建的Flow
提供异步计算的数据的,因为它是挂起函数,所以我们能在里面使用其他挂起函数计算异步值,然后通过emit
方法将值发送出去,如此反复就能为下游操作提供源源不断的数据流了。事情还没完,上面的步骤我们只是规定了创建数据的方式,并没有真正执行,也就是建好了道路,但是还没有车上路。那么,怎样才能让车在路上跑呢,查看Flow
的接口会发现,它提供了collect
方法来处理数据。collect
接收一个挂起函数作为处理逻辑,但是同时,collect
方法本身也是挂起函数,所以,这个方法只能在挂起函数中运行。有了这些知识,我们就可以写出最简单的异步数据流了。
1uspend fun compute():Int{ delay(123) return 1024 } viewModelScope.launch { val flow=flow { emit(9527) emit(compute()) delay(256) emit(256) } flow.collect { println(it) }}
在flow
构造器里面随意做各种操作,只要在必要的时候传递结果就行了,但是需要注意的是,emit
方法只能运行在同一个协程里。乍一看,这样分开写和写在一起并没有本质上的差别,但Flow
还能做到更多。
该给Flow换个工作环境了
上一节,我们那个简单的示例,假如把构造器里面的数据获取方法换成网络请求,应用就歇菜了。因为它们都是运行在主线程里面的。那么这个时候,看过上一篇文章的小伙伴马上就会反应过来,用withContext
方法在构造器里面切换线程就行了哇。思路是很对,因为Flow
的默认配置就是构造器和collect
方法工作在同一线程,既然现在主线程不让运行,那就把构造器的线程切换一下就行了呗。然后事实并不是这样,这样写出来的代码根本无法运行。因为官方提供了唯一的flowOn
方法来切换构造器的执行线程。使用也很简单,就是对创建好的Flow
对象配置一次flowOn
方法就行了。
val flow=["1.jpg","2.jpg"].asFlow()flow.map { decode(it) } .flowOn(Dispatchers.IO)viewModelScope.launch { flow.collect{ adapter.add(it) }
有些中间处理逻辑
熟悉RxJava的小伙伴可能有疑问了,这些操作RxJava也能完成,甚至还有更多的操作符来支持中间状态的处理,那么异步数据流能做到这些吗。毫无疑问,它可以。普通的数据集有map
,filter
等操作方法,对于异步数据流来说,这些方法同样适用。而且这些方法参数都是挂起函数,都可以执行异步操作。而且它还有个更灵活的transform
方法,这个方法可以定制自己的操作符,实现更灵活的数据操作。
当然,上面那些操作符都只能实现单一异步流的操作,对于多数据流的支持,它也同样不在话下。zip
可以将两个两个数据源两两合并起来,合成的数据流长度为两个数据流中最短的那个数据流的长度。combine
则与zip
不同,它会将两个数据流最近的发送数据作为输入,也就是说,假如一块一慢的两个数据源,慢的数据源的元素可能会被多次取到,从而最终的数据流比最短的那个都长。
val flow = flowOf(1, 2).delayEach(10)val flow2 = flowOf("a", "b", "c").delayEach(15)flow.combine(flow2) { i, s -> i.toString() + s }.collect { println(it) // Will print "1a 2a 2b 2c"}
结束状态跟踪
上一节提到,由于数据源和处理逻辑不在同一个地方,所以很难确定最终的数据流大小,进而不知道数据流什么时候处理结束。而且中间操作也可能会改变数据流的大小,由此就更加难以确定数据处理结束的时机了。但是我们有的时候却需要在数据处理完成后做一些操作,该怎么办呢?这个时候当然是该onCompletion
方法上场了。这个方法有一个可为空的Throwable
类型参数,很显然,这可以同时指示两种处理结果,成功或者失败,失败就会将异常对象传递进来。
多个协程共同工作
很多时候,避免不了让多个协程共同工作。对于返回单个值的协程,上一篇我们也提到过了,可以传递async
构造器的返回对象Deferred
,但是局限性就是这个对象只能传递一个值。针对多值传递的情况,Kotlin提供了Channel
的解决方法。Channel
类似于阻塞队列,数据通过send
方法发送出去,在另外的地方使用receive
方法接收。通过这种方法,我们可以极大提供协程的工作效率。利用它就可以轻松实现生产者和消费者模型。
val chanel=Channel() viewModelScope.launch(Dispatchers.IO) { for (i in 1..5){ delay(1000) chanel.send(i) } } viewModelScope.launch { for (i in chanel){ println("Handle ${i}") }}
当然,这只是最简单的用法,还可以加入更多的生产者,或者不再需要数据时取消,甚至还有专门的product
构造器,直接获得返回多个值的协程对象。
总结
Kotlin协程有很多有用的API,这些API覆盖了大部分异步使用的场景。所以在使用协程的时候,我们首先需要明确使用场景,再根据使用场景确定使用哪一套API,这可以使我们避免陷入API恐惧症。为此,我根据这两篇文章的内容,整理出了一份情景表格,实际开发中可以参照使用。Kotlin协程构造器
API | 使用场景 |
---|---|
launch | 执行耗时操作,不需要返回值 |
async | 需要获取耗时操作的单个返回值 |
produce | 需要获取耗时操作的多个返回值 |
Kotlin协程协同工具
API | 使用场景 |
---|---|
Flow | 操作异步数据流 |
Channel | 协程间通信 |
青山不改,绿水长流,咱们下期见!
标签:
抢先读
- 甘州区上秦镇中心学校举办第四届小学生诗词大会
- 房屋拆迁纠纷诉讼时效是多久
- 当前速读:宸展光电:聘任徐可欣担任公司董事会秘书
- 环球头条:2023上海端午节游玩推荐景点有哪些?
- 【环球聚看点】武磊梅开二度,国足4-0胜缅甸!
- 天天看热讯:国产GPU的第一缕光:自研架构“天狼星”在京亮相
- 2023年电子标签产业深度调研及发展趋势预测 今日报
- 个人原因离职申请书范文 全球播资讯
- 上汽大众、上通五菱回暖缓慢,谁来缓解上汽集团的产销焦虑? 环球讯息
- 天天精选!大运会火炬手姜志强:将大运精神延续至赛场外,助推数字经济发展
- 2023粤港澳车展:极狐阿尔法S/T森林版上市 售价18.58万元起
- 谷歌为你准备了一个秘密的片魂复活节彩蛋 天天新要闻
- 京东白条,蚂蚁花呗本质就是信用卡,更方便,自从有了这两样,我信用卡都很少用了-视焦点讯
- 胜利监理(836665):拟10派0.6元,共派现1749.87万元_世界新视野
- 世界观天下!云从科技投资算力芯片企业奕斯伟计算,打通大模型生态闭环
- 16日北京将迎本轮高温峰值 最高气温预计39℃
- 资讯推荐:汽车下乡政策回顾:新能源汽车市场潜力巨大,代步型纯电+平价混动将成为主力产品
- 乌当区2023幼升小入学报名指南(对象+时间+入口+学区划片)_天天快资讯
- 杭州地铁公安公示“偷拍案”处罚信息,律师:有“羞辱性惩罚”和侵犯隐私之嫌_世界今头条
- 世界快讯:甘州区市场监管局西街市场监管所开展早夜市计量器具专项检查
- 公司邀请函
- 世界动态:停息挂账还收利息不?停息挂账之前的利息还需要吗?|天天速看
- 织唛机(织唛) 环球快资讯
- 邓清清 抖音(邓清清) 全球讯息
- 增设电梯陷“拉锯战”:电梯选址距自家仅1米,一楼业主不同意被起诉-天天观天下
- 梅西中国行,有哪些品牌搭上了“顺风车”?
- 世界播报:北京亦庄搭平台助企业共赴双碳之约
- 环球要闻:重症肌无力关爱日|全身渐渐无力,最终唤起心灵之力
- 今日热闻!河南:强化监督执纪 筑牢南水北调工程安全“堤坝”
- 广东最新平均工资出炉!这些行业仍“吃香”→_天天新消息
- 每日视讯:2023南阳端午节游玩景点推荐
- 每日速看!6月FOMC会议点评:“留有余地”的暂停加息
- 天天速递!强观察|这些返回舱里的“神器”为航天员保驾护航
- 跨界布局储能领域!家电龙头获外资连买7日 当前播报
- 天马行空挥洒创意!《狂想乐园》今日上市! 世界速讯
- 高尔夫全锦赛:上海男队和陕西女队继续占据榜首
- 书从文:青海发生山体滑坡(已致5死2失联)
- 中煤国际工程集团武汉设计研究院(关于中煤国际工程集团武汉设计研究院的基本详情介绍)|全球快消息
- word里怎么打钢筋等级符号(钢筋等级符号) 新消息
- 石嘴山市气象台发布大风蓝色预警【IV级/一般】【2023-06-16】
- (聚焦中国高质量发展)以侨为桥 泉州优品“扬帆出海” 天天新资讯
- 北京朝阳区“阅读大运河”系列主题活动启幕 世界实时
- 发改委:研究部署加强居民增收工作 各地要加大稳就业工作力度-即时看
- 金融如何赋能“天府粮仓”建设?崇州这场发布会给出答案_观焦点
- 本周全国碳市场碳排放配额总成交额突破2700万元_全球即时
- “云”上逛房,福利多多,2023齐鲁(济南)夏季房展汇盛大启动-热门看点
- 哈佛医学院丑闻曝光!太平间管理员倒卖遗体,6 人已被逮捕 天天速讯
- 神州播报丨北京警方通报“球迷冲入球场拥抱梅西”事件:已行拘!12个月内不得进体育场馆看同类比赛
- 带你全面提升工作效率:B端设计规范攻略(三)
- 谷歌&凯度:2023年中国全球化品牌50强 比亚迪进入前十
- 市纪委监委下发通知严禁党员干部、公职人员违规操办“学子宴”“谢师宴” 天天热闻
- 福州一商店随便卖红牛被查:没有保健品售卖许可证_新资讯
- 批了!再添一所九年一贯制学校_全球动态
- 《射雕》演员太坎坷,孤独离世、酒店猝死、开煤气自杀,令人惋惜-速看料
- 6月16日内蒙时泰液化天然气价格动态 环球速读
- 速看:sony(lt26ii)
- 性价比神卡!盈通RX 6600显卡降至1399元:8GB显存
- 天天观察:诺安基金韩冬燕在管产品近1年业绩居同类前1%
- 环球聚焦:华尔街大银行裁员人数将超过1.1万人
- 全球速讯:天天速递!信用卡停息挂账后逾期多久会被起诉?网贷逾期了暂时还不上怎么办?
- 通讯!夏夜和夜宵是绝配!餐饮消费催热“夏日夜经济”
- 全球热点!端午节临近 重庆手工现包粽子受热捧
- 下载音乐到U盘怎么下载mp3格式 下载音乐到u盘怎么下载 热点在线
- 葡萄酒怎做的?(葡萄酒怎么做的步骤) 微资讯
- 速看:2023乐华88度温泉乐园端午夜场特惠
- 土拍丨苏系房企成功摇号进京 保利击退石景山区“老地主”
- 韦伯以学术为志业的演讲基调是(韦伯)
- 《萌探》仙侠特辑,娜扎最美,刘令姿最敢,谢娜沾了赵丽颖的光_焦点速递
- 迎峰度夏又至 中国统调电厂存煤达历史新高
- 今日开考!昆明公安护考不松劲! 环球快看
- 快资讯丨2023广州技能入户申请需要什么材料?
- 昱能科技(688348):该股换手率大于8%(06-16)_当前视点
- 天天即时:金价又涨了!2023年6月16日各大金店黄金价格多少钱一克?
- 天天头条:成都春熙路“牵手门”不仅带红了胡总和董小姐,也带红了服装厂
- 天天热议:浙江首票内河运费扣减落地湖州 新举措助力企业新发展
- 【聚看点】滤波器图片(滤波)
- 怎么查电脑IP地址与plc通讯 怎么查电脑ip地址 观天下
- 复星医药:控股子公司注射用拉氧头孢钠获药品注册批准
- 新能源延续反弹,碳中和ETF(159790)盘中拉升,新宙邦涨超7% 环球微资讯
- 天天最资讯丨有一种心态叫平衡(对于有一种心态叫平衡简单介绍)
- 天天快报!【“亮成绩、展形象,二十大精神在支部”一线巡礼】海西德令哈甘南村:城中村的完美“蜕变”
- 环球视讯!财政部:1-5月证券交易印花税收入891亿元 同比下降36.9%
- 亚运会的运动员村什么样?先睹为快→ 世界视点
- 环球快讯:让职业技能在竞赛中提升
- 世界快播:辞退有哪些情形,用人单位如何合法辞退员工
- 今日热门!卤素是什么检测报告 卤素是什么
- 世界观热点:洪城环境:拟收购南昌工贸100%股权
- 世界通讯!事业单位会计做账的步骤 事业单位会计做账流程
- 毛坯墙泛碱怎么处理(毛坯墙起碱处理方法是什么)
- 图表分析怎么写(什么是图表分析法)-世界微速讯
- 第二块和第三块碎片 第二块和第三块
- 为什么小米13边框这么容易花 全球最资讯
- 焦点短讯!新材料产业的五大聚焦
- 南昌西湖区品味粽夏乐购西湖消费券活动时间+领取使用办法
- 环球关注:五部门:截至4月末涉农贷款余额53.16万亿元 同比增长16.4%
- 天天最新:腾讯qq游戏下载2012正式版官方免费下载(下载2012版手机qq
- 今日视点:霸榜3个月,摘地半年签约7成,产品力的破局思维!
- 凌云光06月16日主力大幅流出 环球热点
- 青岛世博园预约及购票入口
- 今日快看!网贷可以停息挂账分期还款吗?网贷逾期了暂时还不上怎么办?-天天微头条