js中给出关于回调函数的解释为:
A callback is a function that is passed as an argument to another function and is executed after its parent function has completed.
意思就是说,回调函数是与其他另外一个函数异步进行的,并且该函数是等待其父函数完成以后才进行
举个例子,函数a中调用了函数b,此时a是b的父函数,b函数要等a执行完后再执行。
这个b函数既可以作为参数的形式传给a函数,这样比较灵活,也可以写死在a函数里面,作为a的函数体
b函数是先摆在那里了,但不是立马就执行,是在a执行后,回头再执行b,回调简单理解就是回头调用嘛
js中的回调函数:
<html>
<head>
<meta charset="UTF-8">
<script language="javascript" type="text/javascript">
function a(callback)
{
alert("我是函数a,我是父函数");
callback();
}
function b(){
alert("我是函数b,是回调函数");
}
function test()
{
a(b);
}
</script>
</head>
<body>
<button onClick=test()>click me</button>
</body>
</html>
本人愚钝,写下疑惑为以后犯糊涂时能醒悟,也希望能帮助和我一样有困惑的人
在理解a,b函数执行先后时出了问题,开始我是这样想的,如果把callback放在a函数第一行,那这不就是先执行了b
函数,然后才执行a函数的么,这算哪门子的回调,后来顿悟,在写a函数的时候,把b函数写在里面,此时没有使用
这个函数,只留了个名字,我未来可以不断的改变这个b函数而相应的改变a函数,这也是回调函数的美妙之处,有点
偏题了,回过来继续说这个,b函数写在a函数体的哪个位置确实会影响b函数和a非b函数的函数体的执行顺序,但是
在开始执行b函数时,已经在执行a函数了。
不知道说明白没有,假如a,b函数都有门,打开a的门已经开始执行a函数了。
jquery中的回调函数,引入了Promise的概念,通过$.Deferred处理过的代码,没有像js中回调的嵌套,如果嵌套太
繁琐使用jquery就更加方便了,主要是三个步骤:
var dtd = $.Deferred(); //创建
dtd.resolve(); //成功
dtd.then() //执行回调
dtd.then() //执行回调
下面看一个代码比较
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script>
</head>
<body>
<button>不使用Deferred处理</button>
<button>使用Deferred处理</button>
<script type="text/javascript">
// 回调处理
$('button:first').click(function() {
alert("不使用Deferred处理");
callback();
});
function callback (){
alert("我是回调函数 b");
}
// jQuery的Deferred处理
$('button:last').click(function() {
function a() {
var dtd = $.Deferred(); // 生成Deferred对象
alert("使用Deferred处理");
dtd.resolve();
return dtd;
}
function ba() {
var dtd = $.Deferred(); // 生成Deferred对象
alert("我是回调函数 ba");
dtd.resolve();
return dtd;
}
var anim = a();
anim.then(function() {
return b();
});
});
</script>
</body>
</html>
【题外话】
js和jquery的回调函数让我想起java中利用多态实现的回调函数,也叫钩子函数
整理到一起方便以后回顾,与上文无关
public class RoomA{
public void paint(){
System.out.println("this is roomA---paint");
}
}
public class Test{
public static void test(RoomB b){
b.paint();//钩子
}
}
public class RoomB extends RoomA{
public void paint(){ //重写父类的方法
System.out.println("this is roomB---paint");
}
}