如何从Job中传播异常?

时间:2017-12-27 12:08:20

标签: kotlin kotlinx.coroutines

来自What is the difference between launch/join and async/await in Kotlin coroutines

  

启动用于解雇和忘记协程。这就像开始一个新线程。如果启动内的代码以异常终止,那么它在线程中被视为未捕获的异常 - 通常在后端JVM应用程序中打印到stderr并崩溃Android应用程序。 join用于等待已启动的协同程序的完成,并且它不会传播其异常。但是,崩溃的子协程也会取消其父级,并带有相应的异常。

如果join没有传播异常,有没有办法等待完成Job呢?

E.g。假设某些库方法返回Job,因为它假定其用户不想传播异常,但事实证明有一个用户确实想要它;该用户可以在不修改库的情况下获取它吗?

1 个答案:

答案 0 :(得分:0)

请使用join + invokeOnCompletion方法

代码将如下所示:

suspend fun awaitError(job: Job): Throwable? {
    val errorAwaiter = CompletableDeferred<Throwable?>();        

    job.invokeOnCompletion { errorAwaiter.complete(it) }

    require(job.IsActive) {
         "Job was completed for too fast, probably error is missed"
    }

    val errorRaised = errorAwaiter.await();

    return when(errorRaised) {
         is CancellationException -> null
         else -> errorRaised
    }
}

请注意,该代码会在快速作业中引发错误,因此请务必小心。在这种情况下,最好返回null(在我的示例中)。