美文网首页
4.协程的异常处理(1)

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

作者: 学吉他的袁先生 | 来源:发表于2020-08-07 17:10 被阅读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启动的协程

    相关文章

      网友评论

          本文标题:4.协程的异常处理(1)

          本文链接:https://www.haomeiwen.com/subject/adqtdktx.html