4.协程的异常处理(1)

2020-08-07  本文已影响0人  学吉他的袁先生

1.讲解异常之前先写这样一个例子
需求异步操作获取用户,主界面展示用户信息,怎么样用协程的方式去写

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的过程中有异常出现怎么处理,比如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()
}

从上面的代码我们可以看出一个异步的请求异常,我们只需要在协程里面try,catch就可以了
这个时候我们再去看开篇协程实现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 同样也是协程上下文,但是不适用于async启动的协程

上一篇下一篇

猜你喜欢

热点阅读