最近在网上看了一些关于回调的博客,感觉大多都含糊不清,绕来绕去,越看越糊涂。今天我在此整理一下我对回调的理解
回调听起来那么高大上,其实和普通的函数调用没有什么区别,只不过是一般函数调用是 A->B->C,而回调是A1->B->A2。我画了三个图,如下:
普通的函数调用,A的方法调用过程中调用B的方法,B的方法跑完后会到A方法中
同步回调,一个线程(多个线程需要阻塞,同步等待)执行到底。
异步回调,在运行B类的方法时新开一个线程,两个线程同时跑。这时假如A中有一个i, 在老线程中循环 i++, 方法2中输出 i ; 当运行到print(i)时假设i++了100次,则输出100,因此异步回调有时也需要同步以免弄脏数据。
这便是回调的基本原理。
众所周知,程序设计的目标之一是低耦合,因为类A和类B是不同的人实现的,假如B是一个非常常用的类,要被封装进JDK中,B的方法在写的时候并不知道A是什么类。这个时候接口的作用就凸显出来了。调用B的时候把接口C作为参数传入,回调的时候再根据接口C调用A的方法。A只需要实现接口C就可以了。
将回调推广到其他语言中也是一样的道理。不管是类的引用函数的引用还是接口的引用,他们的本质都是指针。向B函数中传入A2函数的指针,然后再根据该指针调用A2函数,便实现了回调。
回调的应用场景大多是事件、消息机制、过滤机制。
事件监听线程是一直存在的,这里是注册而非新开一个线程。值得一提的是时间监听线程好像是属于UI线程,因此在里面可以设置组件的属性,然而在自己的新建的线程中修改将会报错。