Kotlin Coroutines从作用域中删除异常处理程序



在下面的代码中,我正在获取一些数据。如果抛出了错误/异常,我希望异常处理程序捕捉到它。一旦完成提取,我将使用LiveData将结果发布给观察的人。

我试图实现的是,一旦我发布结果,异常处理程序就会完成它的工作。这意味着,如果处理结果的观察者也抛出异常,我不希望协程异常处理程序捕获它(下面的代码就是这样(。

fun loadPrerequisites(resultObserver: MutableLiveData<PrerequisiteDataHolder?>) {
val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
resultObserver.postValue(null)
}
scope.launch(Dispatchers.IO + exceptionHandler) {
val deferredCreationScheme = async {
fetchCreationScheme()
}
val creationScheme = deferredCreationScheme.await()
//TODO remove exception handler at this stage?
resultObserver.postValue(PrerequisiteDataHolder(creationScheme))
}
}

在将结果发布到LiveData之前,是否有方法删除异常处理程序?或者我必须引入一个新的范围吗?

您似乎误解了协程异常处理程序的用途。它是Java中uncaughtExceptionExceptionHandler的协同程序等价物,其目的是通知您已经破坏其协同程序的异常。您似乎希望使用它来实现业务逻辑级别的异常处理。

协程异常处理程序不能替代try-catch块,后者是您在案例中应该使用的。

我认为你的代码一开始就不需要async,我相信这就是你真正需要的:

scope.launch(Dispatchers.IO) {
resultObserver.postValue(
try {
PrerequisiteDataHolder(fetchCreationScheme())
} catch (e: Exception) {
null
}
)
}

我通常会为这样的代码使用一个助手函数:

inline fun <T> tryOrNull(block: () -> T) = try {
block()
} catch (t: Throwable) {
null
}

然后你的代码变成

scope.launch(Dispatchers.IO) {
tryOrNull { PrerequisiteDataHolder(fetchCreationScheme()) }
.also { resultObserver.postValue(it) }
}

最新更新