返回

协程函数withContext、launch和async的比较

Android

前言

在使用Kotlin协程时,有几个不同的函数可以用于启动协程,包括withContextlaunchasync。这些函数各有其独特的用途和适用场景。本文将通过一个示例比较这三个函数,帮助读者理解它们的异同。

示例

假设我们有一个简单的Kotlin协程函数,它将一个列表中的数字求和并打印出来:

fun main() = runBlocking {
    val numbers = listOf(1, 2, 3, 4, 5)
    val sum = numbers.sum()
    println("The sum of the numbers is $sum")
}

现在,让我们使用withContextlaunchasync三个函数来重写这个示例。

使用withContext

fun main() = runBlocking {
    val numbers = listOf(1, 2, 3, 4, 5)
    withContext(Dispatchers.IO) {
        val sum = numbers.sum()
        println("The sum of the numbers is $sum")
    }
}

在上面的示例中,我们使用withContext函数来指定协程将在哪个调度器上运行。在这里,我们使用Dispatchers.IO,它是一个专门用于执行I/O操作的调度器。

withContext函数的语法是withContext(context: CoroutineContext, block: suspend () -> Unit)。第一个参数是协程上下文,它指定了协程将在哪个调度器上运行。第二个参数是一个挂起函数块,它包含了协程要执行的代码。

使用launch

fun main() = runBlocking {
    val numbers = listOf(1, 2, 3, 4, 5)
    launch(Dispatchers.IO) {
        val sum = numbers.sum()
        println("The sum of the numbers is $sum")
    }
}

在上面的示例中,我们使用launch函数来启动一个协程。launch函数的语法是launch(context: CoroutineContext, block: suspend () -> Unit)。第一个参数是协程上下文,它指定了协程将在哪个调度器上运行。第二个参数是一个挂起函数块,它包含了协程要执行的代码。

launch函数与withContext函数的区别在于,launch函数不会等待协程执行完毕。它会在协程启动后立即返回,而协程则会继续在后台执行。

使用async

fun main() = runBlocking {
    val numbers = listOf(1, 2, 3, 4, 5)
    val sum = async(Dispatchers.IO) {
        numbers.sum()
    }
    println("The sum of the numbers is ${sum.await()}")
}

在上面的示例中,我们使用async函数来启动一个协程并返回一个Deferred对象。async函数的语法是async(context: CoroutineContext, block: suspend () -> T)。第一个参数是协程上下文,它指定了协程将在哪个调度器上运行。第二个参数是一个挂起函数块,它包含了协程要执行的代码。

async函数与launch函数的区别在于,async函数会返回一个Deferred对象,该对象表示协程的计算结果。我们可以使用await()方法来等待协程执行完毕并获取计算结果。

比较

下表总结了withContextlaunchasync三个函数的异同:

函数 等待协程执行完毕 返回值
withContext
launch
async Deferred<T>

适用场景

  • withContext函数适用于需要在协程中执行一些需要阻塞操作的任务,如访问数据库或文件系统。
  • launch函数适用于需要在协程中执行一些不