异步作业取消导致父作业取消

Eri*_*Lin 3 kotlin kotlin-coroutines

我尝试运行两个异步作业。

有一个按钮,单击后会取消其中一项作业。但我注意到当我这样做时,其他工作也会被取消。

发生了什么?

class SplashFragment : BaseFragment(R.layout.fragment_splash), CoroutineScope by MainScope() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    launch {
        val countdown = async { countDown() }
        val ipAndMaintain = async { checkIPAndMaintain() }

        btnSkip.onClick {
            countdown.cancel() // cancel countdown
            btnSkip.isVisible = false
            if (!ipAndMaintain.isCompleted) {
                showLoadingDialog()
            }
        }
        countdown.await()
        startOtherPage(ipAndMaintain.await())
    }
}

private suspend fun countDown() {
    var time = 3
    while (time >= 0) {
        btnSkip.text = getString(R.string.skip, time)
        delay(1000)
        yield()
        time--
    }
}

private suspend fun checkIPAndMaintain(): Int {
    delay(2000)
    return 1
}
Run Code Online (Sandbox Code Playgroud)

}

Gle*_*val 6

当您await调用已取消的操作时Deferred,它会抛出异常。如果您没有捕获它,那么它将传播到父协程,父协程将取消其所有子协程。用countdown.await()一个块包裹你的指令try-catch,你会看到另一个协程继续运行。这就是结构化并发的效果。

您可以阅读Roman Elizarov撰写的有关该主题的文章