launch
和 async
launch
:在協程內部馬上拋出異常,未捕獲的異常不會被保存, join
中也不會保存和傳遞異常,可是會接受由父協程傳遞過來的 JobCancellationException
。async
:不在協程內部馬上拋出異常,而將未捕獲的異常保存在生成的 Deferred
中,最後拋出時已經回到父協程了。coroutineScope
和 supervisorScope
coroutineScope
內部的異常會向上傳播,子協程未捕獲的異常會向上傳遞給父協程,任何一個子協程異常退出,會致使總體的退出。supervisorScope
內部的異常不會向上傳播,一個子協程異常退出,不會影響父協程和兄弟協程的運行。try {
coroutineScope {
try {
val child1 = launch {
log("Child1 is started")
delay(100)
throw ArithmeticException("Child1 error")
}
child1.join()
} catch (e: Exception) {
log("Child1: $e")
}
try {
val child2 = launch {
log("Child2 is started")
delay(1000)
log("Child2 is finished")
}
child2.join()
} catch (e: Exception) {
log("Child2: $e")
}
}
} catch (e: Exception) {
log("Parent: $e")
}
複製代碼
切換外層的 coroutineScope
和 supervisorScope
,再對 child1
切換使用 launch
和 async
,最後獲得下表html
條件 | child1 的 catch | child 2 的 catch | parent 的 catch |
---|---|---|---|
coroutineScope + launch | JobCancellationException | Child1 error | |
coroutineScope + launch + join | JobCancellationException | JobCancellationException | Child1 error |
coroutineScope + async | JobCancellationException | Child1 error | |
coroutineScope + async + await | Child1 error | JobCancellationException | Child1 error |
supervisorScope + launch | JobCancellationException | Child1 error | |
supervisorScope + launch + join | Child1 error | JobCancellationException | Child1 error |
supervisorScope + async | |||
supervisorScope + async + await | Child1 error |
launch
不管其父協程做用域是 coroutineScope
仍是 supervisorScope
,都會致使整個父協程做用域範圍內的協程的退出。而且由於 join
不會保存和傳播異常,即便 launch
自己在外部 try/catch
裏執行了 join
,catch
中捕獲的也只是由父協程發出的取消。async
async
由於是將未捕獲的異常保存在生成的 Deferred
中,在父協程做用域是 coroutineScope
時,雖然一樣由於將異常拋給父協程致使整個父協程做用域範圍內的協程的退出。可是在外部 try/catch
裏執行 await
時, catch
也可以捕獲發生在 async
內部的異常。在父協程做用域是 supervisorScope
是,該 async
的崩潰不會影響兄弟協程和父協程其餘代碼的運行。spa
一般狀況下,使用經常使用的 coroutineScope
+ launch
,將異常捕獲寫在 launch
中就能夠了。.net
但在同時運行多個子協程時,有兩種狀況下,使用 supervisorScope
+ async
更爲便利。code
try/catch
,且一個協程的崩潰不能致使全部協程的退出try/catch
,可是對全部協程拋出的異常處理邏輯是相同的,且一個協程的崩潰應致使全部協程的退出參考文章 :協程
Kotlin協程中的launch/join和async/await之間有什麼區別htm
異常處理作用域