• kotlin协程withContext的使用


    众所周知,async和launch是启动协程的两种方式。由于我们知道async是用来取回结果的,所以只有当我们需要并行执行时才应该使用&,而launch则是当我们不想取回结果时使用,用于更新等操作我们知道,到目前为止,异步是启动协程并返回结果的唯一方法,但是当我们不想进行并行网络调用时,异步就会出现问题。众所周知,使用async时,需要使用 await ()函数,这会导致主线程阻塞,但是这里引入了withContext的概念,解决了主线程阻塞的问题。

    withContext 只是编写异步的另一种方式,无需编写await()。使用 withContext 时,它会串行而不是并行运行任务。因此,应该记住,当我们在后台有一个任务并且想要返回该任务的结果时,我们应该使用 withContext。让我们举一个例子来演示 withContext 的工作原理:

    1. // two kotlin suspend functions
    2. // Suppose we have two tasks like below
    3. private suspend fun doTaskOne(): String
    4. {
    5. delay(2000)
    6. return "码农乐园"
    7. }
    8. private suspend fun doTaskTwo(): String
    9. {
    10. delay(2000)
    11. return "kotlin withContext"
    12. }

    让我们使用 async-await 并行运行这两个任务,然后使用 withcontext 来看看两者之间的区别。

    1. // kotlin function using async
    2. fun startLongRunningTaskInParallel()
    3. {
    4. viewModelScope.launch
    5. {
    6. val resultOneDeferred = async { TaskOne() }
    7. val resultTwoDeferred = async { TaskTwo() }
    8. val combinedResult = resultOneDeferred.await()
    9. + resultTwoDeferred.await()
    10. }
    11. }

    这里使用异步,两个任务并行运行。现在让我们使用 withContext 并使用withContext连续执行相同的任务。

    1. // kotlin function using withContext
    2. fun startLongRunningTaskInParallel()
    3. {
    4. viewModelScope.launch
    5. {
    6. val resultOne = withContext(Dispatchers.IO) { TaskOne() }
    7. val resultTwo = withContext(Dispatchers.IO) { TaskTwo() }
    8. val combinedResult = resultOne + resultTwo
    9. }
    10. }

    这里可以看到,在withContext中一切都是一样的,唯一的区别是这里我们不必使用await ()函数,并且任务是以串行方式执行的。由于这里已经执行了多个任务,因此应该记住 async 应该与多个任务一起使用,而 withContext 应该与单个任务一起使用。现在我们举个例子,尝试详细了解 withContext 以及它是如何执行的;

    1. // sample kotlin program for complete
    2. // demonstration of withContext
    3. fun testWithContext
    4. {
    5. var resultOne = "码农乐园"
    6. var resultTwo = "testWithContext"
    7. Log.i("withContext", "Before")
    8. resultOne = withContext(Dispatchers.IO) { function1() }
    9. resultTwo = withContext(Dispatchers.IO) { function2() }
    10. Log.i("withContext", "After")
    11. val resultText = resultOne + resultTwo
    12. Log.i("withContext", resultText)
    13. }
    14. suspend fun function1(): String
    15. {
    16. delay(1000L)
    17. val message = "function1"
    18. Log.i("withContext", message)
    19. return message
    20. }
    21. suspend fun function2(): String
    22. {
    23. delay(100L)
    24. val message = "function2"
    25. Log.i("withContext", message)
    26. return message
    27. }
  • 相关阅读:
    Mangopi MQ-R:T113-s3编译Tina Linux系统(二)SDK目录
    前端自动生成二维码并长按识别跳转 Vue
    CF803F
    15、简单了解Vue
    爬虫 — 多线程
    初出茅庐的小李博客之Windows11运行Linux记录
    广义线性模型(GLM)及其应用
    代码随想录刷题|LeetCode 70. 爬楼梯(进阶) 322. 零钱兑换 279.完全平方数
    二、体验Linux系统(文件目录、shell)
    计算机网络面试核心--网络基础知识
  • 原文地址:https://blog.csdn.net/qxf865618770/article/details/132820330