IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Kotlin协程的挂起函数编写(六) -> 正文阅读

[移动开发]Kotlin协程的挂起函数编写(六)

一、前言

在之前的例子中,我们知道可以通过launch或者async来启动协程,并可以控制其生命周期,而且还知道了通过async的异步可以做到并行运行。这里记录一下其它的操作

二、延迟启动协程

协程可以通过提前定义,然后当某一条件触发时候再进行启动,如下

private suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

private suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}
@Test
fun lazy(){
    runBlocking {
        val time = measureTimeMillis {
            val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
            val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
            // some computation
            one.start() // start the first one
            two.start() // start the second one
            println("The answer is ${one.await() + two.await()}")
        }
        println("Completed in $time ms")
    }
}

对于延时启动的函数,可以使用Job.start()或者Deffered.await()来进行启动,不过这里的话先使用Job.start()启动再使用Deffered.await()来获取结果,因为这样才不会导致并行的程序因为await()变成串行程序

三、GlobalScope.async

其实官方是不建议直接使用GlobalScope启动协程的因为不好控制。例如我们编写一个异步的任务(异步任务通常使用"…Async"的方式命名)。

  • GlobalScope是一个微妙的 API,可能会以非平凡的方式适得其反,下面将解释其中一种方式,因此您必须明确选择使用@OptIn(DelicateCoroutinesApi::class)
// The result type of somethingUsefulOneAsync is Deferred<Int>
@OptIn(DelicateCoroutinesApi::class)
fun somethingUsefulOneAsync() = GlobalScope.async {
    doSomethingUsefulOne()
}

// The result type of somethingUsefulTwoAsync is Deferred<Int>
@OptIn(DelicateCoroutinesApi::class)
fun somethingUsefulTwoAsync() = GlobalScope.async {
    doSomethingUsefulTwo()
}

通过GlobalScope.async启动的代码可以在任何地方执行异步操作,如下

// The result type of somethingUsefulOneAsync is Deferred<Int>
@OptIn(DelicateCoroutinesApi::class)
fun somethingUsefulOneAsync() = GlobalScope.async {
    doSomethingUsefulOne()
}

// The result type of somethingUsefulTwoAsync is Deferred<Int>
@OptIn(DelicateCoroutinesApi::class)
fun somethingUsefulTwoAsync() = GlobalScope.async {
    doSomethingUsefulTwo()
}
@Test
fun taskAsync(){
    runBlocking {
        // note that we don't have `runBlocking` to the right of `main` in this example
            val time = measureTimeMillis {
                // we can initiate async actions outside of a coroutine
                val one = somethingUsefulOneAsync()
                val two = somethingUsefulTwoAsync()
                // but waiting for a result must involve either suspending or blocking.
                // here we use `runBlocking { ... }` to block the main thread while waiting for the result
                runBlocking {
                    println("The answer is ${one.await() + two.await()}")
                }
            }
            println("Completed in $time ms")
    }
}

这个代码本身没有问题,倘若出于某种原因协程要取消掉,比如出现异常,在val one = somethingUsefulOneAsync()one.await()中间出现错误,那么即使明确调用了cancel()somethingUsefulOneAsync()还是会在后台默默运行。这里可以使用coroutineScope来解决这个问题。所以需要修改为以下方式

suspend fun concurrentSum(): Int = coroutineScope {
    val one = async { doSomethingUsefulOne() }
    val two = async { doSomethingUsefulTwo() }
    one.await() + two.await()
}
@Test
fun taskAsync(){
    runBlocking {
      val time = measureTimeMillis {
          println("The answer is ${concurrentSum()}")
      }
      println("Completed in $time ms")
    }
}

这是因为coroutineScope函数是个挂起函数在调用的地方需要跟使用它的作用域绑定,这样当作用域取消时,这个函数的内容也取消了。

四、参考链接

  1. 编写挂起函数

    https://kotlinlang.org/docs/composing-suspending-functions.html#lazily-started-async

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-31 16:45:30  更:2021-07-31 16:46:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 2:11:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码