本篇将介绍一下什么是回调地狱
回调地狱
异步编程 之一 回调地狱
对于回调地狱(Callback hell),想必大家都不陌生,但是在RxJava、Reactor等反应式编程框架兴起之后,对于回调地狱只是听得多,但是见得的少。所以接下来将介绍一下什么是回调地狱
回调函数
要了解什么是回调地狱,那就得先了解一下什么是回调。简单来说回调就是:调用者在调用被调用者后,被调用者进行操作并将结果反馈给调用者。这个过程就是回调

代码讲解
普通回调
回调嘛,得先创建个Callback接口,用来回调
1
2
3
4
5
6
7interface Callback<T> {
/**
* 定义一个回调的接口,方便下面的实现
*/
fun callback(value: T)
}接下来我们就已工作中上司和下属来作为例子。创建上司
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// 上司肯定要有下属嘛,所以得就将下属传进来
class Boss(private val subordinate: Subordinate) : Callback<String> {
override fun callback(value: String) {
println("上司收到通知:工作${value}已完成")
}
/**
* Boss安排任务
*/
fun arrangeWorker(worker: String) {
println("上司开始安排任务")
Thread{ // 开启了个新线程来通知下属去工作
subordinate.work(worker, this)
}.start()
println("老板下班^^")
}
}老板分配工作,员工去完成,如果完成过程是异步,则是
异步调用,如果是同步的,则是同步回调,我们这里采用异步方式。创建下属
1
2
3
4
5
6class Subordinate {
fun work(worker: String, callback: Callback<String>) {
println("下属接到指令,开始处理工作${worker}") // 处理工作
callback.callback("${worker}已完成")// 将任务完成结果反馈给上司
}
}下属类很简单,就只接受任务就行了(打工人冲!)
接下来就开始回调
1
2
3
4
5fun main() {
Boss(Subordinate()).run {
arrangeWorker("扫地")
}
}打印结果为:
1
2
3
4上司开始安排任务
上司下班^^
下属接到指令,开始处理工作扫地
上司收到通知:工作扫地已完成已完成上述代码可以看到异步回调是不会阻塞主线程的,上司在任务发布完之后就下班了,之后下属完成任务之后再通过另一个线程通知上司
地狱
既然要展示地狱,那肯定要再嵌套一层。设计如下

现在老板需要产品经理来设计产品并获得设计好的产品
更改一下arrangeWorker里面的内容
1
2
3
4
5
6
7
8
9
10
11
12
13class Boss(private val subordinate: Subordinate) : Callback<String> {
...
fun arrangeWorker(worker: String) {
println("老板通知产品经理进行设计")
Thread {
subordinate.work(worker, this)
}.start()
println("老板下班^^")
}
...
}通知完产品经理,收到回调后,那就得让开发来进行开发了嘛
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21class Boss(private val subordinate: Subordinate) : Callback<String> {
override fun callback(value: String) {
println("老板通知:产品经理已将${value}设计好了")
val newWork = "$value 系统"
println("产品经理设计完成,再将任务交给开发")
Subordinate().work(newWork, object : Callback<String> {
override fun callback(value: String) {
println("开发:开发${value}完毕")
}
})
}
fun arrangeWorker(worker: String) {
println("老板通知产品经理进行设计")
Thread {
subordinate.work(worker, this)
}.start()
println("老板下班^^")
}
}于是再老板的回调中,再创建一个开发并开一个新的回调
运行看一下把,输入Ios
1
2
3
4
5
6
7老板通知产品经理进行设计
老板下班^^
下属接到指令,开始处理工作Ios
老板通知:产品经理已将Ios设计好了
产品经理设计完成,再将任务交给开发
下属接到指令,开始处理工作Ios 系统
开发:开发Ios 系统完毕
好啦,一个简单的回调地狱就完成了,其实回调地狱就是回调嵌套回调,但是如果嵌套层数过多,仿佛掉入地狱,于是有了回调地狱的说法。
优势
那这有啥优点嘛?
- 优点还是有的:回调地狱给我们带来什么?事实上,回调的代码如同管道一样,接收输入,并将处理后的内容输出至下一步。而回调地狱,则是多个管道连接,形成的一个流程,而各个子流程(管道)相互独立。
缺点
缺点很明显
- 当然缺点很明显:回调的方法虽然将子过程解耦,但是回调代码的可读性降低、复杂性大大增加。看得我头晕,真的