 在 Kotlin 中處理協程的例外時,確保正確處理例外並避免常見的陷阱是很重要的。 # **使用 `try-catch` 處理例外** - 如果你只是在協程中進行一般的例外處理,可以使用 `try-catch`。但要注意,`try-catch` 應該直接包住可能會拋出例外的代碼,而不是包住整個協程,這樣可以避免吞掉不應該被捕獲的例外,例如取消例外。 ```kotlin lifecycleScope.launch { try { // 可能拋出例外的代碼 val result = apiCall() // 處理結果 } catch (e: HttpException) { // 處理特定的 HTTP 例外 } } ```  # **使用 `CoroutineExceptionHandler`** - 如果你需要處理未捕獲的例外,你可以使用 `CoroutineExceptionHandler`。這是一個協程上下文,用來處理未捕獲的例外。你需要在最外層的協程中安裝這個處理器。 ```kotlin val handler = CoroutineExceptionHandler { _, exception -> println("Caught exception: $exception") } lifecycleScope.launch(handler) { launch { // 可能會拋出未捕獲例外的代碼 throw RuntimeException("Something went wrong") } } ```  # **理解 `async` 的例外處理** - 當你使用 `async` 時,例外不會立即拋出,而是在調用 `await` 時才會拋出。因此,確保在調用 `await` 時正確處理例外。 ```kotlin val deferred = lifecycleScope.async { // 可能會拋出例外的代碼 throw RuntimeException("Something went wrong") } lifecycleScope.launch { try { val result = deferred.await() } catch (e: Exception) { println("Caught exception in async: $e") } } ```  # **使用 `supervisorScope` 避免協程相互影響** - 如果你不希望一個協程的失敗導致其他協程被取消,可以使用 `supervisorScope`。這樣即使一個協程失敗,其他協程仍然可以繼續執行。 ```kotlin supervisorScope { launch { // 這個協程失敗不會影響其他協程 throw RuntimeException("Failure in coroutine 1") } launch { // 即使前一個協程失敗,這個仍會繼續執行 println("Coroutine 2 is running") } } ```  # **避免吞掉取消例外** - 當你在協程中使用 `try-catch` 時,如果遇到 `CancellationException`,應該將其重新拋出,這樣可以確保協程正確地取消。 ```kotlin try { // 可能會拋出例外的代碼 } catch (e: Exception) { if (e is CancellationException) throw e // 處理其他例外 } ```  # 總結  協程的例外處理與一般的同步程式不同,你需要特別注意例外的傳播方式和取消機制。使用正確的方式處理例外,不僅能保證程式的穩定性,還能避免一些隱藏的陷阱。 
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up