从回调中继续挂起函数

Continue suspend functions from callback

我正在使用 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 工件,它包含一小组用于在协程和任务之间进行转换的实用程序 API(在其他 Play 相关库中也很常见)。

您应该能够用暂停 Task.await() 扩展函数替换基于回调的 API (addOnCompleteListener()):

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() 也是 returns 展开的结果(Task<T> 中的 T)。

在幕后,它使用 suspendCancellableCoroutine. Source code is available here.

Task<T>.addCompleteListener() 转换为挂起函数