4.協(xié)程的異常處理(1)

1.講解異常之前先寫這樣一個例子
需求異步操作獲取用戶,主界面展示用戶信息,怎么樣用協(xié)程的方式去寫

typealias CallBack=(User)->Unit
fun getUser(callback: CallBack){
    thread {
        log(1)
        var user=User("he",23)
        callback.invoke(user)
    }
}
suspend fun getUserCoroutine()= suspendCoroutine<User> {
    continuation->
    getUser {
        continuation.resume(it)
    }
}
suspend fun main(){
    GlobalScope.launch (Dispatchers.Main){
        val name = getUserCoroutine().name
        val age = getUserCoroutine().age
        log(name+age)
    }.join()
}

思考如果獲取user的過程中有異常出現(xiàn)怎么處理,比如name為空字符串的user視為異常

interface MyCallBack<T>{
    fun onSuccess(value:T)
    fun onError(t:Throwable)
}
fun getUserWithError(callback: MyCallBack<User>){
    //模擬異步操作
    thread {
        log(1)
        var user=User("",23)
        if (user.name.isEmpty()){
            callback.onError(Throwable("姓名為空"))
        }else{
            callback.onSuccess(user)
        }

    }
}
suspend fun getUserCoroutineWithError()= suspendCoroutine<User> {
    continuation->
    getUserWithError(object :MyCallBack<User>{
        override fun onSuccess(value: User) {
            continuation.resume(value)
        }

        override fun onError(t: Throwable) {
            continuation.resumeWithException(t)
        }

    })
}
suspend fun main(){
    GlobalScope.launch {
        try {
            val user = getUserCoroutineWithError()
            log(user.name)
        }catch (t:Throwable){
            log(t)
        }
    }.join()
}

從上面的代碼我們可以看出一個異步的請求異常,我們只需要在協(xié)程里面try,catch就可以了
這個時候我們再去看開篇協(xié)程實現(xiàn)retrofit請求,就理解為什么可以這樣子寫

GlobalScope.launch {
    try {
        val weatherEntity = apiService.getMessage3("鄭州")
        println(weatherEntity.temperature)
    }catch (e:Throwable){
        println(e.message)
    }
}

還有一種異常捕獲方式,不需要寫try,catch

suspend fun main(){
    val coroutineExceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
        log(throwable)
    }
    GlobalScope.launch(coroutineExceptionHandler) {
        val user = getUserCoroutineWithError()
        log(user.name)
    }.join()
}

CoroutineExceptionHandler 同樣也是協(xié)程上下文,但是不適用于async啟動的協(xié)程

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容