协程的优势是什么?
很多人在看这篇文章前就差不多知道了什么是协程,网上也有很多的论调,比如轻量级的线程,减少了上下文切换的开销等等。我们也可以将协程简单的认为,协程就是将阻塞代码运行在另一个线程。
协程的出现对于我们程序员来说有什么好处呢?提升程序性能么?那仅仅是对程序而言。以我个人的角度看来,协程为开发者带来了两个好处。
1、简化异步编程的难度。
2、增强开发者对业务的理解。
我们现在有这么一段非协程的异步代码。常规的异步代码往往通过回调进行数据处理,如下所示。
fun loadData(){ networkRequest(){data->
show(data)
} }
fun networkRequest(onSuccess: (Data)->Unit){
DefaultScheduler.execute{
postToMainThread(onSuccess(result))
}
}
上面的代码看着挺好理解的,但是我们现实开发的逻辑往往不会这么简单,容易,在不使用第三方库的情况下,我们会遭遇如下的一个问题,多层回调嵌套,也就是说我们在异步请求的时候,往往会使用该异步请求的结果,然后触发另一个或多个异步请求。Google对于这种情况给了一个名词——Callback Hell(回调地狱)
fun loadData(){ networkRequest(){data-> secondNetworkRequest(data){secondData-> ..... NthNetworkRequest(N-1thData){NthData-> dosomething(NthData) } } } }
越来越多的回调往往会将开发者的注意力偏移开发本身,而协程可以帮我们解决这个问题,接下来我们看看用协程写异步代码是如何开发的。
suspend fun loadData(){ val data = networkRequest()
val result = secondNetworkRequest(data) show(result) }
suspend fun networkRequest():Data=
withContext(Dispatchers.IO){ //这里是通过withContext将程序调度到IO线程
doSomething()
}
suspend fun secondNetworkData(data:Data):Result=
withContext(Dispatchers.IO){ //这里是通过withContext将程序调度到IO线程
doSomething()
}
上面便是一个简单的协程代码,我们可以发现相比较于之前采用回调的方式,用协程写的代码更加符合我们开发者的思考习惯,甚至我们感觉它更像一段同步代码,这里面也便涉及了我提到的协程第二个好处,通过同步的方式开发异步代码,其实同步的逻辑更符合我们开发者的思考习惯,而协程通过这种方式,能够帮助开发者更好的理解业务代码。当然协程内部是如何实现这种写法的,我们这里便不再展开了,有兴趣的同学可以去了解一下。
通过这几段代码的展示,我们可以感觉到协程的出现,确实让我们开发者有了更好的编程体验,接下来的文章来看看开发者如何在开发中使用协程,以及为什么协程代码可以这样去写。