【问题标题】:Continue suspend functions from callback继续挂起回调函数
【发布时间】:2021-04-09 18:27:17
【问题描述】:

我使用 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() 之前完成。

【问题讨论】:

  • 我认为你应该让 firebase 操作同步,比如 await()

标签: android kotlin kotlin-coroutines coroutinescope


【解决方案1】:

您可以使用 kotlinx-coroutines-play-services artifact,其中包含一小组用于在协程和 Tasks 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() 还返回一个解包结果(Task<T> 中的T)。

在后台,它使用suspendCancellableCoroutineTask<T>.addCompleteListener() 转换为挂起函数。源代码可在here获取。

【讨论】:

  • 感谢您的回答。实际上,我正在将回调转换为挂起函数(点击此链接medium.com/swlh/…)。然后问题只是结果类型在将挂起函数的结果转换为布尔值时不断收到一些运行时错误。如果我不能解决这个问题,我会尝试 google play 中的库
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多