那些迷糊人的回调

在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作为实参执行了回调函数,这样子就实现了我们的回调目的。
posted @ 2017-04-09 17:37  dearxiangxiao  阅读(210)  评论(0编辑  收藏  举报