亲宝软件园·资讯

展开

kotlin协程coroutineScope函数

最爱大头猫 人气:0

正文

public suspend fun <R> 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

代码分析

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

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有如下语义:

加载全部内容

相关教程
猜你喜欢
用户评论