1.协程-为何要用协程

Posted 黄毛火烧雪下

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1.协程-为何要用协程相关的知识,希望对你有一定的参考价值。

一、 什么是协程

  • 1.协程是 kotlin 为我们提供的线程切换框架,它和 AsyncTask 丶 RxJava 干的事情一样;
  • 2.协程并不会提高效率,只会提高代码的可读性;
  • 3.协程并不是线程,他只负责切换线程。
    在这里插入图片描述

二、 android的切换线程历史

先说作用之前,我们来说下 Android 线程切换的的历史。

讲解之前个大家提醒一个实战用例,大伙可以想一想,用下面的线程切换技术你会如何实现呢?
1:一个界面需要 2 个接口同时请求成功,当 2 个接口都请求成功的时候渲染界面(注意:2 个接口需要在2个线程中请求哦)。
2:1个界面需要 2 个接口顺序请求,第二个接口需要依赖第一个接口的返回数据做参数。

  • 1.本质 Handler 切换
    有人会说:用 Handler 切换也挺开心的啊?我用 Handler 切换线程超级牛B,我连 Handler 原理都知道的一清二楚的。其实这种方式切换线程的致命缺点就是 地狱回调.
    在这里插入图片描述
  • 2.AsyncTask封装
    其实 AsyncTask 就是对异步任务做了一次封装(好像所有的框架都是封装)。但是治标不治本,还是规避不了地狱回调的问题,还且很多场景无法使用。
    在这里插入图片描述
  • 3.一直到 RxJava 的出现 Android 的这个问题才有所缓解。当我第一次使用 RxJava 的时候,我发现这东西真是太好用了,但是我发现这个东西学习成本非常高。操作符的复杂,以及原理都非常难理解。让我 RxJava 从入门到放弃。

到这里,大家应该发现上面的 3 种方案每一种都有一些弊端,相比较最好的方案应该就是 RxJava 的流失线式的切线程更为的智能,并且异常也能统一管理。

  • 4.Kotlin 的推广带来了新的切线程方案,它可以以同步代码的写法写出异步的功能。

三、协程的作用

通过上面的讲解,我们知道了所有的线程框架,都想解决一个问题 地狱回调 问题。那么我们理想的线程切换是啥样的呢?来看下伪代码:

void initView() {
    // 主线程展示加载Dialog
    展示加载Dialog()
    // 异步网络请求等待数据返回
    val data = 异步请求网络数据()
    // 主线程dismissDialog()
    消失Dialog()
    // 主线程渲染View
    主线程根据数据展示修改View状态(data)
}

看上面的伪代码,大家思考下 Java 能实现这样的功能吗?仔细想 Java 是不可能的实现这样的代码,语法根本不支持,Java 中不可能存在异步方法能返回数据。
最终协程就是为了解决这个问题而诞生。哪有人说 Java 不支持,作为儿子的 Kotlin 协程怎么会支持呢?其实 Koltin 能实现这样的代码是因为 Kotlin 的编译器欺骗了你的眼睛

fun initView() {
    启动一个协程 {
        // 1:主线程展示加载Dialog
        展示加载Dialog()
        // 2:异步网络请求,执行一个挂起函数
        val data = 异步请求网络数据()
        // 3:主线程dismissDialog()
        消失Dialog()
    }
}

看上方的伪代码,我们首先启动了一个协程,剩下的主要有 3 句代码,第一句代码没啥好说的。

关键在第二句代码 协程 有一个挂起的概念,意思是我执行一个挂起函数,调用我的主线程你可以去干其他事啦,等我干完事情我再通知你,执行我后面的第三句代码。

仔细回味第二句代码的解释有没有类似回调的意思?我们经常写的回调函数的作用,不就是通知我们做完事情了吗?

其实 Kotlin 的协程挂起函数实现原理就是通过回调来实现的。你看似 1 2 3 句代码写在一起,其实在编译后的 Class 字节码并不是写在一起的, Kotlin 的编译器欺骗了你的眼睛。

四、总结

通过上面的解释,我们最终总结下 Kotlin 的协程?

  • 1.协程的目的是想让我们用同步代码,写出异步功能
  • 2.协程负责帮我们在执行完挂起函数后切换线程
  • 3.挂起函数最终也是通过回调函数来实现的
  • 4.协程写的同步代码看似写在一起,其实最终编译后挂起函数前后的代码是分开的。

最后提醒大家,不要用看 Java 代码的思想,去看 Kotlin 的协程,不然你会进入一个闭环的。因为有时候你眼睛看到的和最终生成的 Java 代码是不一样的,Kotlin 的编译器会欺骗你的眼睛。

以上是关于1.协程-为何要用协程的主要内容,如果未能解决你的问题,请参考以下文章

linux陷入回调陷阱,用协程解决异步转同步

golang为什么用协程而不是线程

为啥 LiveData 没有从协程更新?

在laravel5.8中集成swoole组件----用协程实现的服务端和客户端---静态文件如何部署

协程-浅谈2

Python基础-协程