一、概念
回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。
咋一看回调函数的概念,可能并不能立即理解什么是回调函数。通俗的讲,回调函数就是以函数作为参数传给另一个函数执行。比如:有一个函数A,函数B,
将A函数作为B函数的参数,然后在B函数里执行A函数,这就是最简单的回调。
var A = function(){ console.log("我是回调函数A。"); }; var B = function(callback){ console.log("我是主函数B内的代码。"); callback(); }; B(A);
这下大伙应该能理解什么是回调了吧。估计大伙会想,这样的回调有意义吗?把A函数的代码直接写到B函数里面不是更好吗?
如果在实际项目里这样写回调真的是糟糕透了。往下看,了解回调是如何应用的。
二、同步回调和异步回调
什么,回调不是异步的吗?仔细看看上面的例子,大家就能明白,回调不一定都是异步的,他有同步和异步之分。上面的示例就是一个同步回调,
所以我不想在过多的解释什么是同步回调,接下来,我们看看什么是异步回调。
由于 JS 是单线程的,一旦我们要执行一个长耗时的任务时,如果一直单线程的堵塞下去会导致程序的等待时间过长而使页面失去响应,非常影响用户体验。
为了解决这样的问题,我们就可以使用异步回调。将耗时的任务扔给异步去做,做好了再通知下我们做完了,我们拿到数据继续往下走。
下面是 ajax 异步请求的部分代码:
var xhr; ...... xhr.onreadystatechange = function(){ if(xhr.readystate === 4 && xhr.status === 200){ //do something } }
当浏览器发起 ajax 请求的时候,会单开一个线程发起 http 请求,这样就能把耗时的 http 请求独自运行。在请求的过程中 readystate
的值会不断的变化,对应着不同的请求状态。大家看看 jquery 对 ajax 的封装就能明白,它就是根据 readystate 返回的状态,执行不
同的回调,最常用的两个回调应该是 success 函数和 error 函数。
异步回调的应用,如下,有 A 和 B 两个函数:
//一般情况下,应该是这样的 A(); B(); //当 A 函数是一个长耗时任务时,为了解决 A 函数长时间阻塞页面问题 //可以将 B 函数作为 A 函数的回调执行 function A(callback){ setTimeout(function () { // A 的任务代码 callback(); }, 3000); } A(B);
因为 JS 是单线程的,所以异步回调也不是真正意义上的异步,它只不过是一个伪异步执行,它通常利用定时器和条件判断来伪装异步执行。