继续挂起回调函数

问题描述

我使用 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 工件,其中包含一小组用于在协程和 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() 还返回一个解包结果(T 中的 Task<T>)。

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...