本文介绍了何时使用coroutineScope与SupervisorScope?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以解释这两者之间到底有什么区别吗?

Can someone explain what exactly is the difference between these two?

您何时在另一个上使用?

When do you use one over the other?

谢谢.

推荐答案

解释差异的最好方法是解释coroutineScope的机制.考虑以下代码:

The best way to explain the difference is to explain the mechanism of coroutineScope. Consider this code:

suspend fun main() = println(compute())

suspend fun compute(): String = coroutineScope {
    val color = async { delay(60_000); "purple" }
    val height = async<Double> { delay(100); throw HttpException() }
    "A %s box %.1f inches tall".format(color.await(), height.await())
}

compute()从网络中获取两件事,并将它们组合为字符串描述.在这种情况下,第一次获取会花费很长时间,但最终会成功;第二个在100毫秒后几乎立即失败.

compute() fetches two things from the network and combines them into a string description. In this case the first fetch is taking a long time, but succeeds in the end; the second one fails almost right away, after 100 milliseconds.

您想要上述代码的什么行为?

What behavior would you like for the above code?

  1. 您想color.await()一分钟,只是想知道另一个网络通话已长期失败吗?

  1. Would you like to color.await() for a minute, only to realize that the other network call has long failed?

或者您想让compute()函数在100毫秒后意识到其网络调用之一失败并立即自身失败?

Or perhaps you'd like the compute() function to realize after 100 ms that one of its network calls has failed and immediately fail itself?

使用supervisorScope可获得1.,使用coroutineScope可获得2.

With supervisorScope you're getting 1., with coroutineScope you're getting 2.

2的行为意味着,即使async本身并没有引发异常(它只是完成了从中获得的Deferred),但故障立即取消了其协程,从而取消了父级,从而取消了父级.然后取消所有其他孩子.

The behavior of 2. means that, even though async doesn't itself throw the exception (it just completes the Deferred you got from it), the failure immediately cancels its coroutine, which cancels the parent, which then cancels all the other children.

当您不知道此行为时,可能会很奇怪.如果您从await()捕获异常,您会认为您已经从中恢复了,但还没有.整个协程范围仍然被取消.在某些情况下,您有一个不合理的理由,那就是您使用supervisorScope.

This behavior can be weird when you're unaware of it. If you go and catch the exception from await(), you'll think you've recovered from it, but you haven't. The entire coroutine scope is still being cancelled. In some cases there's a legitimate reason you don't want it: that's when you'll use supervisorScope.

这篇关于何时使用coroutineScope与SupervisorScope?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 05:00