今天偶然想起在做开发的时候经常会用到回调函数,似乎自己都记不得是在哪里第一次听到这个名词了,总之只记得是一开始我并不是先完全了解了它的概念才使用它的,而是直接上手使用,导致了一直以来我就觉得回调函数就是当我执行完什么函数后要做什么处理的时候就把它写到回调函数中传过去。其实现在想想理解的是不对的,也就又花时间去学习了一下回调函数的概念,但是我发觉很多说法可能不是那么的通俗易懂,于是就想分享下我所理解的回调函数,用简单的方式说明白什么是回调函数。
按照概念上描述的回调函数是把一个函数作为参数传递给另一个函数,而这个被当作参数传入的函数就是回调函数,然后再由被传入函数的特定的事件发生的时候来执行这个回调函数。所以并不是我曾经理解的一定是当函数执行完自己的逻辑之后才调用回调函数的,回调函数在什么时候执行,其实取决于事件,而事件本身是你自己定义的,只不过通常大部分时候你更关心某个逻辑执行完之后你要做些什么,比如游戏开发中当你加载完某些资源后你要做些什么,而加载资源通常是异步的,你并不希望程序阻塞在那里一直加载,而是需要一个函数处理当程序加载完之后做些什么(比如loading完进入场景)。那么总结下来回调函数就是把一个函数当作参数传递给另外一方,然后另外一方在函数运行到某些你想要处理的时候再去执行。而这些在像Lua等语言中其实是很好实现的,因为Lua中函数是可以存在变量中的,比如你会看到类似下面这样的代码:
local callBack = function ()
print("animation finished")
end
a.playAnimation("attack",callBack)
假设playAnimation是一个用来播放动画的函数,然后当动画播放完毕以后你想做些事情,就可以写一个callBack函数传递给playAnimation,然后playAnimation会在执行完播放attack动画后调用它。所以这里的callBack就是一个典型的回调函数。
但是在Java中由于函数不能当作变量来使用,所以在实现毁掉函数时可以通过接口来实现。比如我们先顶一个接口叫做CallBack:
public interface CallBack {
public void onStart();
public void onFinish();
}
然后我们定义一个类Work,这个Work可以理解为你要做的具体的业务处理。
public class Work {
public void doWork(CallBack callback){
callback.onStart();
System.out.println("do my work-----------------------");
callback.onFinish();
}
}
它包含一个doWork的方法来处理自己的业务,比如我们这里就是输出一句话 do my work,doWork方法需要传入一个实现了CallBack接口的类的对象,而我们想要关心两个事件处理的点,一个是在执行我得业务逻辑之前调用onStart,一个是当我的业务逻辑执行完之后的onFinish方法,这也就是回调函数概念中所说的“特定的事件发生的时候来执行这个回调函数”。最后我们再写一个测试类来运行一下看看:
public class TestCallBack {
public static void main(String[] args) {
Work work = new Work();
work.doWork(new CallBack() {
@Override
public void onStart() {
// TODO Auto-generated method stub
System.out.println("work begin--------------");
}
@Override
public void onFinish() {
// TODO Auto-generated method stub
System.out.println("work finish--------------");
}
});
}
}
运行的话就会依次看到打出的log了,以上就是我对回调函数的理解,其实只要明白原理,在不同的语言里都很容易实现,回调函数并不是什么难以理解的概念。