【问题标题】:How to propagate exceptions from a Job?如何从作业传播异常?
【发布时间】:2018-06-08 02:01:16
【问题描述】:

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

launch 用于触发和忘记协程。这就像开始一个新线程。如果启动中的代码因异常而终止,则将其视为线程中未捕获的异常——通常在后端 JVM 应用程序中打印到 stderr 并使 Android 应用程序崩溃。 join 用于等待启动的协程完成,它不会传播其异常。但是,崩溃的子协程也会取消其父协程,并出现相应的异常。

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

例如假设某个库方法返回一个Job,因为它假设它的用户不想传播异常,但事实证明确实有一个用户想要它;这个用户可以在不修改库的情况下得到它吗?

【问题讨论】:

  • 谢谢你的这个问题,我现在也想知道。你找到解决办法了吗?
  • 我不记得了,很遗憾。但我不这么认为。

标签: kotlin kotlinx.coroutines


【解决方案1】:

请使用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

【讨论】:

    猜你喜欢
    • 2022-07-28
    • 2012-06-28
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 2016-06-24
    • 2015-12-25
    • 2020-11-15
    相关资源
    最近更新 更多