android - 继续从回调中挂起函数

标签 android kotlin kotlin-coroutines coroutinescope

我使用 firestore 作为我的后端数据库,保存我的数据如下所示:

suspend fun uploadDataToFirestore() {
  val firestore = Firebase.firestore
  var batch = firestore.batch
 
 -- fill batch with data --

  batch.commit().addOnCompleteListener {
    if (it.isSuccessful) {
      Timber.d("Successfully saved data")
     
      doAdditionalSuspendingStuff()
            
    } else {
      Timber.d("error at saving data: ${it.exception}")     
    }
}
 

问题出在 onCompleteListener 内部,因为我无法调用其他挂起函数。有没有办法从 onCompleteListener 中调用挂起函数,但使它们仍然附加到同一作用域,因为我不希望函数 uploadDataToFirestore 完成直到 doAdditionalSuspendingStuff() 被执行。

最佳答案

您可以使用kotlinx-coroutines-play-services Artifact ,其中包含一小组用于在协程和任务 API 之间进行转换的实用程序(您也会在其他 Play 相关库中找到它们)。

您应该能够将基于回调的 API ( addOnCompleteListener() ) 替换为挂起 Task.await()扩展功能:

suspend fun uploadDataToFirestore() {
    val firestore = Firebase.firestore
    val batch = firestore.batch

    try {
        batch.commit().await() // Suspend the coroutine while uploading data.

        Timber.d("Successfully saved data")
        doAdditionalSuspendingStuff()
    } catch (exception: Exception) {
        Timber.d("error at saving data: $exception")     
    }
}

await()还返回展开的结果( T 中的 Task<T> )。

在幕后它转换Task<T>.addCompleteListener()使用 suspendCancellableCoroutine 进入挂起函数。源代码可用here .

关于android - 继续从回调中挂起函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65554594/

相关文章:

android - Android 中 Google map 中两个 GeoPoint 之间的线?

android - 记录 Xamarin 未处理(Android 未捕获)异常

android - 如何在时间选择器中将文本 “cancel”更改为android kotlin中的另一个文本?

kotlin - 之前在 Kotlin

android - 如何从协程 kotlin 获取值(value)?

android - IONIC 电容器 BLE 插件扫描不起作用

android - 将 Handler 用作计时器但无法停止

kotlin - 修改扩展函数中的 "this"

list - 如何从非流函数获取流输出

android - 使用 Koin 注入(inject) CoroutineDispatcher