如何将Android任务转换为Kotlin Deferred?

JP *_*ura 8 android kotlin firebase kotlinx.coroutines

Firebase匿名登录返回任务(基本上是Google承诺实施):

val task:Task<AuthResult> = FirebaseAuth.getInstance().signInAnonymously()
Run Code Online (Sandbox Code Playgroud)

如何创建一个signInAnonymous包装器:

  • 这是一个suspend功能,等待task完成

    • suspend fun signInAnonymous(): Unit
  • 它返回一个Deferred对象,异步传递结果

    • fun signInAnonymous() : Deferred

Dav*_*uel 18

该软件包kotlinx.coroutines.tasks现在包括以下实用程序功能:

public suspend fun <T> Task<T>.await(): T { ... }
Run Code Online (Sandbox Code Playgroud)

文档

等待任务完成而不阻塞线程。
此暂停功能是可以取消的。
如果当前协程的Job在此挂起函数等待时被取消或完成,则此函数将停止等待完成阶段并立即以CancellationException恢复。

public fun <T> Task<T>.asDeferred(): Deferred<T> { ... }
Run Code Online (Sandbox Code Playgroud)

文档

将此任务转换为Deferred的实例。
如果任务被取消,那么产生的延迟也将被取消。


所以你可以这样做:

suspend fun signInAnonymouslyAwait(): AuthResult {
    return FirebaseAuth.getInstance().signInAnonymously().await()
}
Run Code Online (Sandbox Code Playgroud)

或者:

fun signInAnonymouslyDeferred(): Deferred<AuthResult> {
    return FirebaseAuth.getInstance().signInAnonymously().asDeferred()
}
Run Code Online (Sandbox Code Playgroud)

  • 对于那些寻找 Maven 存储库的人来说,它是 [kotlinx-coroutines-play-services](https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-play-services) (2认同)

zsm*_*b13 9

基于这个GitHub库,这里有一种方法可以Task"通常"的方式将一个转换为一个挂起函数,以使基于异步调用的回调适应协程:

suspend fun <T> Task<T>.await(): T = suspendCoroutine { continuation ->
    addOnCompleteListener { task ->
        if (task.isSuccessful) {
            continuation.resume(task.result)
        } else {
            continuation.resumeWithException(task.exception ?: RuntimeException("Unknown task exception"))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您也可以将它包装在一起Deferred,CompletableDeferred在这里派上用场:

fun <T> Task<T>.asDeferred(): Deferred<T> {
    val deferred = CompletableDeferred<T>()

    deferred.invokeOnCompletion {
        if (deferred.isCancelled) {
            // optional, handle coroutine cancellation however you'd like here
        }
    }

    this.addOnSuccessListener { result -> deferred.complete(result) }
    this.addOnFailureListener { exception -> deferred.completeExceptionally(exception) }

    return deferred
}
Run Code Online (Sandbox Code Playgroud)


Cyb*_* Gh 6

将其添加到 gradle

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.4.3'
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

suspend fun login(email: String, pass: String) {
    FirebaseAuth.getInstance().signInWithEmailAndPassword(email, pass).await()
}
Run Code Online (Sandbox Code Playgroud)