如何使用 Kotlin 协程执行顺序后台任务

42 篇文章 1 订阅

如何使用 Kotlin 协程执行顺序后台任务

coroutines-deal-seq-tasks

Kotlin 协程,谁不知道协程!因此,在这篇文章中,我们会讲到其中一个重要的部分,就是制作顺序后台任务。
大家好,我是 Abanoub,在这篇文章中,我将向您展示如何使用async和await以及使用withContext 的另一种方法使用协程来执行顺序后台任务。

顺序意味着如果你有3个任务,第一个任务将运行,第二个任务将在第一个任务完成后执行,第三个任务将在第二个任务完成后执行,依此类推。
1. 添加协程依赖
您需要将 kotlin 协程依赖项添加到您的build.gradle应用程序模块:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'

 
 
  • 1
  • 2

然后同步你的项目,让我们开始吧。

2. 创建一个CoroutineScope 实例。

这将定义协程将在其中运行的上下文。

val myScope = CoroutineScope(Dispatchers.IO)

 
 
  • 1

3.创建一些后台任务作为挂起函数

 suspend fun doTask1() {
        repeat(5) { i ->
            Log.d("CoroutinesTasks", "doTask1: $i")
        }
    }
<span class="token keyword">suspend</span> <span class="token keyword">fun</span> <span class="token function">doTask2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">repeat</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> i <span class="token operator">-&gt;</span>
        Log<span class="token punctuation">.</span><span class="token function">d</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"CoroutinesTasks"</span></span><span class="token punctuation">,</span> <span class="token string-literal singleline"><span class="token string">"doTask2: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$</span><span class="token expression">i</span></span><span class="token string">"</span></span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">suspend</span> <span class="token keyword">fun</span> <span class="token function">doTask3</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">repeat</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> i <span class="token operator">-&gt;</span>
        Log<span class="token punctuation">.</span><span class="token function">d</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"CoroutinesTasks"</span></span><span class="token punctuation">,</span> <span class="token string-literal singleline"><span class="token string">"doTask3: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$</span><span class="token expression">i</span></span><span class="token string">"</span></span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

现在我们已经创建了三个挂起函数,每个函数将打印一条日志 5 次,这是对后台任务的简单模拟,例如使用 Room 或 Retrofit 制作任务。

4. 使用异步和等待

要按顺序运行这些任务,您可以使用asyncawait函数。async 创建一个新的 Coroutine 并返回一个Deferred对象,而await等待 Coroutine 的结果并返回它的值。

val myScope = CoroutineScope(Dispatchers.IO)
        myScope.launch {
            Log.d("CoroutinesTasks", "onCreate: Started") 

在此示例中,我们使用async按顺序运行每个任务,并使用await等待其结果。这确保了每个任务都按照我们想要的顺序执行,而不会阻塞主线程。

现在,如果你运行这个应用程序,你会看到这样的结果:

  1. 开始执行第一个任务,直到第一个任务完成后才执行第二个任务。
  2. 第一个任务完成,其结果存储在 result1 变量中。
  3. 开始执行第二个任务,直到第二个任务完成后才开始执行第三个任务。
  4. 第二个任务完成,它的结果存储在 result2 变量中。
  5. 开始执行第三个任务,直到第三个任务完成后才开始执行它之后的任何事情。
  6. 第三个任务完成,结果保存在result3变量中。
 D  onCreate: Started
                   D  doTask1: 0
                   D  doTask1: 1
                   D  doTask1: 2
                   D  doTask1: 3
                   D  doTask1: 4
                   D  doTask2: 0
                   D  doTask2: 1
                   D  doTask2: 2
                   D  doTask2: 3
                   D  doTask2: 4
                   D  doTask3: 0
                   D  doTask3: 1
                   D  doTask3: 2
                   D  doTask3: 3
                   D  doTask3: 4
                   D  onCreate: Ended

那么,什么是result1、result2、result3呢?

这些是结果,假设你在第一个任务中从 api 中获得了一个数据列表,那么 result1 将是这个列表,但是 suspend 函数返回类型应该是你想要作为结果获取它的数据,并且在第二个任务中,你会将这个列表保存到数据库中,然后你将它正常传递给第二个任务,我们将在一个例子中解释这一点。

5. 使用withContext()

您也可以使用withContext函数获得相同的结果。

 val myScope = CoroutineScope(Dispatchers.IO)
        myScope.launch {
            Log.d("CoroutinesTasks", "onCreate: Started") 
 
 

将顺序后台任务定义为单独的挂起函数。例如,如果你想执行一个网络请求,然后是数据库访问,你可以定义两个单独的挂起函数:

suspend fun fetchPosts(): List<Post> {
    // Perform network request
    return myApi.getPosts()
}

suspend fun savePosts(posts: List<Post>) {
// Save data to database
myDao.savePosts(posts)
}

withContext 块中一个接一个地调用顺序后台任务。这将确保每个任务按顺序运行并且不会阻塞 UI 线程。例如:

myScope.launch {
    val posts = withContext(Dispatchers.IO) {
        fetchPosts()
    }
    withContext(Dispatchers.IO) {
        savePosts(posts)
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值