当前位置: 首页 > news >正文

1.5-协程基础与关键知识:连接线程的世界-回调型 API 协作

文章目录

  • 线程 API 转换成挂起函数:suspendCoroutine
  • 支持取消的 suspendCoroutine:suspendCancellableCoroutine
  • 总结

线程 API 转换成挂起函数:suspendCoroutine

在实际项目中即使已经使用协程了,可是要完全避免跟传统的线程 API 交互并不容易,大型项目一般都会有比较多的老代码或外部库没有用协程,使用的还是回调的写法。那么就很有必要知道怎么让协程和线程 API 的回调交互。

协程有一个专用的函数 suspendCoroutine,它是一个挂起函数,在它里面调用传统的回调式函数,就能把回调式的函数转换成挂起函数

lifecycleScope.launch {val contributors = callbackToSuspend()showContributors(contributors)
}private suspend fun callbackToSuspend() = suspendCoroutine {gitHub.contributorsCall("square", "retrofit").enqueue(object : Callback<List<Contributor>> {override fun onResponse(call: Call<List<Contributor>>, response: Response<List<Contributor>> {// 将结果返回it.resume(response.body()!!)}override fun onFailure(call: Call<List<Contributor>>) {// 发生异常时让 suspendCoroutine 立即结束并抛出这个异常it.resumeWithException(t)}})}
}

使用 suspendCoroutine 包裹的回调式代码需要调用 suspendCoroutine 提供的 continuation.resume 和 continuation.resumeWithException 分别处理正常返回结果和异常的情况

支持取消的 suspendCoroutine:suspendCancellableCoroutine

协程还提供了一个类似的函数 suspendCancellableCoroutine,和 suspendCoroutine 的区别是它支持取消

private suspend fun callbackToCancellableSuspend() = suspendCancellableCoroutine {it.invokeOnCancellation {// 协程被取消,处理协程被取消时要做的一些收尾工作清理现场}gitHub.contributorsCall("square", "retrofit").enqueue(object : Callback<List<Contributor>> {override fun onResponse(call: Call<List<Contributor>>, response: Response<List<Contributor>> {// 将结果返回it.resume(response.body()!!)}override fun onFailure(call: Call<List<Contributor>>) {// 发生异常时让 suspendCoroutine 立即结束并抛出这个异常it.resumeWithException(t)}})}
}

使用 suspendCancellableCoroutine 还可以注册取消的回调,使用 cancellableContinuation.invokeOnCancellation 处理协程被取消时的收尾清理工作

我们用一个例子来说明 suspendCoroutine 和 suspendCancellableCoroutine 的区别:

val job = lifecycleScope.launch {// 假设 callbackToSuspend 会在延时 2s 后继续执行try {val contributors = callbackToSuspend()// val contributors = callbackToCancellableSuspend()showContributors(contributors)} catch (e: Exception) {textView.text = e.message}
}
lifecycleScope.launch {delay(200)job.cancel() // 200ms 后取消协程
}

假设 callbackToSuspend 函数是使用 suspendCoroutine 包起来的回调代码,会在 2s 后返回结果;协程 200ms 后被取消了,但是里面的代码是不配合的,因为协程的取消本身就是一个状态标记,2s 后还是会继续执行代码。

而如果用 suspendCancellableCoroutine 在 200ms 后会正常取消协程,会在 try-catch 抛出 CancellableException 异常,不会在继续执行后续代码。

我们一般在项目中都使用能支持取消的 suspendCancellableCoroutine,除非特殊需求需要启动后协程取消了也得继续执行才用 suspendCoroutine

总结

  • 将线程 API 的回调式代码用 suspendCoroutine 或 suspendCancellableCoroutine 包住,就能实现将回调式代码转换为挂起函数在协程执行,需要调用提供的 continuation.resume 和 continuation.resumeWithException 分别处理正常返回结果和异常的情况

  • suspendCancellableCoroutine 和 suspendCoroutine 的区别是它支持取消和注册协程取消回调;我们一般在项目中都使用能支持取消的 suspendCancellableCoroutine,除非特殊需求需要启动后协程取消了也得继续执行才用 suspendCoroutine

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 《0基础》学习Python——第十五讲
  • Docker安装Zookeeper、RocketMQ
  • 【源码阅读】osproxy对象存储分布式代理(1)
  • Python面试题:在 Python 中,如何使用 multiprocessing 模块?
  • SpringBoot+HttpClient实现文件上传下载
  • LabVIEW异步和同步通信详细分析及比较
  • 0基础学python-14:python进阶之面向对象
  • Linux指令ros学习python深度学习bug学习笔记
  • 景区客流统计系统提升服务精准度
  • 深入理解Session和Cookie的作用与联系
  • 《汇编语言 基于x86处理器》- 读书笔记 - Visual Studio 2019 配置 MASM环境
  • 产品经理-一份标准需求文档的8个模块(14)
  • 亚信安全发布2024年第24期《勒索家族和勒索事件监控报告》
  • LabVIEW比例压力控制阀自动测试系统
  • 前端学习常用技术栈
  • Google 是如何开发 Web 框架的
  • canvas绘制圆角头像
  • HTML5新特性总结
  • Java 最常见的 200+ 面试题:面试必备
  • Java知识点总结(JavaIO-打印流)
  • laravel 用artisan创建自己的模板
  • node-glob通配符
  • passportjs 源码分析
  • Python进阶细节
  • SSH 免密登录
  • 动态规划入门(以爬楼梯为例)
  • 多线程事务回滚
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 详解NodeJs流之一
  • 字符串匹配基础上
  • scrapy中间件源码分析及常用中间件大全
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • #pragam once 和 #ifndef 预编译头
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (04)odoo视图操作
  • (1)常见O(n^2)排序算法解析
  • (8)STL算法之替换
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (libusb) usb口自动刷新
  • (pycharm)安装python库函数Matplotlib步骤
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (六)Hibernate的二级缓存
  • (一)Dubbo快速入门、介绍、使用
  • (转)Sublime Text3配置Lua运行环境
  • (转)详解PHP处理密码的几种方式
  • .equals()到底是什么意思?
  • .mysql secret在哪_MySQL如何使用索引
  • .net Stream篇(六)
  • .net 受管制代码