当前位置:主页 > android教程 > kotlin协程coroutineScope函数

kotlin协程之coroutineScope函数使用详解

发布:2023-03-06 16:00:01 59


给网友们整理相关的编程文章,网友束晗日根据主题投稿了本篇教程内容,涉及到kotlin协程coroutineScope函数、kotlin、coroutineScope、kotlin协程coroutineScope函数相关内容,已被234网友关注,如果对知识点想更进一步了解可以在下方电子资料中获取。

kotlin协程coroutineScope函数

正文

public suspend fun  coroutineScope(block: suspend CoroutineScope.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return suspendCoroutineUninterceptedOrReturn { uCont ->
        val coroutine = ScopeCoroutine(uCont.context, uCont, true)
        coroutine.startUndispatchedOrReturn(coroutine, block)
    }
}

它是一个suspend函数,创建一个新的协程作用域,并在该作用域内执行指定代码块,它并不启动协程。其存在的目的是进行符合结构化并发的并行分解(即,将长耗时任务拆分为并发的多个短耗时任务,并等待所有并发任务完成后再返回)。

coroutineScoperunBlocking的区别在于runBlocking会阻塞当前线程,而coroutineScope会挂起所在的协程直至其内部任务(包括子协程)执行完成,它不会阻塞所在的线程。

coroutineScope是一个挂起函数,它被挂起后,会转而执行之前的子协程。

fun main() = runBlocking {
    launch {        //launch①       
        delay(1000)                 //挂起launch①
        println("test2")
    }
    println("test1")
    coroutineScope {                //第一次挂起runBlocking,直至内部逻辑完成
        launch {    //launch②
            delay(2000)             //挂起launch②
            println("test3")
        }
        delay(5000)     //delay①    //第二次挂起runBlocking
        println("test4")
    }
    println("test5")
}
//test1
//test2
//test3
//test4
//test5

代码分析

  • runBlockingmain线程创建并启动一个阻塞的协程;
  • 创建launch①子协程,由于创建协程是需要一些时间的,并且协程的创建是由特定的线程来完成,并非是main线程。所以在创建协程过程中会并行地执行后续代码。因此test1被输出。
  • 执行到coroutineScope函数时,把runBlocking挂起,直到内部逻辑执行完成。
  • 然后创建launch②协程,创建过程中执行执行后续代码:delay①继续挂起runBlocking5s(挂起函数中调用挂起函数)。
  • 等到launch①创建完毕时,把它挂起1s。launch②创建完毕时,把它挂起2s。
  • 此时runBlocking、launch①、launch②都是被挂起状态。
  • 等到1s后launch①恢复,输出test2;2s后launch②被恢复,输出test3;5s后runBlocking第二次挂起被恢复,输出test4
  • 此时coroutineScope中的逻辑已经执行完成,恢复runBlocking的第一次挂起,test5被输出。

这比较难以理解,下面的案例稍微容易些:

fun main() = runBlocking {
    launch {
        println("test3")
    }
    println("test1")
    coroutineScope {    //挂起runBlocking,直到内部逻辑完成
        println("test2")
        delay(1000)     //挂起runBlocking5s
        println("test4")
    }
    println("test5")    //必须等待挂起函数coroutineScope执行完毕后才会被执行
}
//test1
//test2
//test3
//test4
//test5

而如果把coroutineScope函数改成delay函数,会更加容易理解,因为它们都是挂起函数。

fun main() = runBlocking {
    launch {
        delay(1000)
        println("test2")
    }
    println("test1")
    delay(2000)     //挂起runBlocking协程2s
    println("test3")
}
//test1
//test2
//test3

coroutineScope经常用来把一个长耗时的任务拆分成多个子任务,使这些子任务并行执行

suspend fun showSomeData() = coroutineScope {
    val data1 = async {         //子任务1
        delay(2000)
        100
    }
    val data2 = async {         //子任务2
        delay(3000)
        20
    }
    withContext(Dispatchers.Default) {      //合并结果并返回
        delay(3000)
        val random = Random(10)
        data1.await() + data2.await() + random.nextInt(100)
    }
}

coroutineScope有如下语义:

  • 并行执行内部任务data1data2withContext
  • 如果其它任务(random)抛出异常,data1data2两个任务会被取消
  • 如果showSomeData()被取消,内部的data1data2withContext都会被取消
  • 如果data1data2失败,withContext被取消。

以上就是kotlin协程之coroutineScope函数使用详解的详细内容,更多关于kotlin协程coroutineScope函数的资料请关注码农之家其它相关文章!


参考资料

相关文章

  • Kotlin浅析null操作方法

    发布:2023-03-03

    Kotlin对比于Java的一个最大的区别就是它致力于消除空引用所带来的危险。在Java中,如果我们尝试访问一个空引用的成员可能就会导致空指针异常NullPointerException(NPE)的出现。在Kotlin语言中就解决了这个问题,下面来看看它是如何做到的


  • Kotlin Flow操作符及基本使用详解

    发布:2023-03-03

    这篇文章主要为大家介绍了Kotlin Flow操作符及基本使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪


  • Kotlin 嵌套函数开发技巧详解

    发布:2023-03-04

    这篇文章主要为大家介绍了Kotlin 嵌套函数开发技巧详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪


  • Kotlin扩展方法超详细介绍

    发布:2023-03-12

    Kotlin 可以为一个不能修改的或来自第三方库中的类编写一个新的函数。 这个新增的函数就像那个原始类本来就有的函数一样,可以用普通的方法调用,这种机制的函数称为扩展函数


  • Kotlin中@JvmOverloads注解作用示例介绍

    发布:2023-03-07

    在Kotlin中@JvmOverloads注解的作用就是:在有默认参数值的方法中使用@JvmOverloads注解,则Kotlin就会暴露多个重载方法。可能还是云里雾里,下面来详细了解


  • Kotlin扩展函数超详细介绍

    发布:2023-03-05

    Kotlin 可以为一个不能修改的或来自第三方库中的类编写一个新的函数。 这个新增的函数就像那个原始类本来就有的函数一样,可以用普通的方法调用,这种机制的函数称为扩展函数


  • Kotlin作用域函数应用详细介绍

    发布:2023-03-02

    作用域函数:是Kotlin标准库中的内联函数,作用在对象上时,执行给定的block代码块。可以在block代码块中通过it,this代表当前对象,进行代码逻辑处理


  • Kotlin协程开发之Flow的融合与Channel容量及溢出策略介绍

    发布:2023-03-05

    这篇文章主要介绍了Kotlin协程:Flow的融合、Channel容量、溢出策略,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧


网友讨论