在jquery里,我们看到过无数种类的回调,最典型的莫过于jquery封装的ajax里面的回调,例如:
$.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston",
success: function(msg){
alert( "Data Saved: " + msg );
},
error:function(){
alert("error!")
}
});
简单的说,就是往后台下发一个POST请求,当往正常返回值时调用sueccess函数,有错时调用error函数,具体为什么会这么调用,在另外的博文里我会继续探讨。那么,来看看这个回调到底是怎么玩的,我们常说的异步执行和回调又有着怎样的关系,为什么一直就是搞不清楚这二者的区别呢?
先来看一个例子:
var quadratic = function(a){
return a*a;
};
假若现在有这样的一个场景,先需要做两个数字平方的操作,再把这两个平方求和,那么我们可以先计算平方,再计算加和,这个计算加和的函数,我们直接就调用这个addCal函数即可了,那么,我们可以这样子做:把这个addCal函数当初参数传入,先求算两个数字的平方,再调用加和的函数,最后返回求和之后的值,不就行了吗?说干就干。我写出了这么一段代码:
function quadraticSum(a,b,quadratic){
return quadratic(a) + quadratic(b);
};
将addCal函数传给形参cb,这样就能将5和1这两个变量保留下来,供后面使用,调用时,写法如下:
var result = quadraticSum(5,12,quadratic);
console.log(result); //结果是 169
那么函数也是可以作为参数进行传递的,上面的这个例子到底是不是一个回调呢?答案是否定的,这不是一个回调,尤其是并没有标定在quadraticSum执行完之后再执行quadratic函数,这里是执行quadraticSum的同时,在其内部执行quadratic函数,因此,严格的说,这个并不能算是真正的回调函数。
于是,我们一定要清楚,必须是在外部函数已经完全执行完毕,再来调用的那个函数,才称其为回调函数,请注意这里一定是要在前面外部的那个函数的函数体执行完之后,再执行的函数才成为回调函数,它一般在同步情境下是最后执行的,而在异步情境下有可能不执行,因为事件没有被触发或者条件不满足。
现在来看看下面这个真正的回调例子:
function a(callback){
alert(‘a‘);
callback.call(this);//callback()或者callback.apply(this)都是可以的
}
function b(){
alert(‘b‘);
}
a(b);
这样的结果是先弹出 ‘a‘,再弹出‘b’。再看一个有参数传递的,毕竟这种带参数的函数也占到大多数,一起看看吧。
function fn1(callback){
var sum =0;
for(var i= 1; i< 100000; i++){
sum = sum + i;
};
console.log(sum);
callback.call(this,sum);
};
fn1(function(arg){
console.log("The sum result is "+arg);
}); //调用结果为 The sum result is 4999950000
这里专门布置了一个超级大的for循环,并且设置了参数传入的场景,我们可以看到,如期执行完了整个for循环,执行了匿名的回调函数,将sum作为实参执行了回调函数,这样子就实现了我们的回调目的。