协程函数withContext、launch和async的比较
2023-11-06 09:13:53
前言
在使用Kotlin协程时,有几个不同的函数可以用于启动协程,包括withContext
、launch
和async
。这些函数各有其独特的用途和适用场景。本文将通过一个示例比较这三个函数,帮助读者理解它们的异同。
示例
假设我们有一个简单的Kotlin协程函数,它将一个列表中的数字求和并打印出来:
fun main() = runBlocking {
val numbers = listOf(1, 2, 3, 4, 5)
val sum = numbers.sum()
println("The sum of the numbers is $sum")
}
现在,让我们使用withContext
、launch
和async
三个函数来重写这个示例。
使用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()
方法来等待协程执行完毕并获取计算结果。
比较
下表总结了withContext
、launch
和async
三个函数的异同:
函数 | 等待协程执行完毕 | 返回值 |
---|---|---|
withContext |
是 | 无 |
launch |
否 | 无 |
async |
是 | Deferred<T> |
适用场景
withContext
函数适用于需要在协程中执行一些需要阻塞操作的任务,如访问数据库或文件系统。launch
函数适用于需要在协程中执行一些不