js回调函数原理及应用

编程分为两类:系统编程(system programming)和应用编程(application programming)。
所谓系统编程,简单来说,就是编写库;而应用编程就是利用写好的各种库来编写具某种功用的程序,也就是应用。系统程序员会给自己写的库留下一些接口,即API(application programming interface,应用编程接口),以供应用程序员使用。所以在抽象层的图示里,库位于应用的底下。当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。

1.什么是回调?
简单说:回调是一个在另一个函数完成执行后所执行的函数——故此得名“回调”。
更复杂地说:在 JavaScript 中,函数是对象。因此,函数可以将函数作为参数,并且可以由其他函数返回。执行此操作的函数称为高阶函数。任何作为参数传递的函数都称为回调函数。

2.为什么我们需要回调?
一个非常重要的原因—— JavaScript 是一种事件驱动的语言。这意味着,在继续之前, JavaScript 不会等待响应,而是继续执行且同时监听事件。我们来看一个简单的例子:

function first(){
  console.log(1);
}
function second(){
  console.log(2);
}
first();
second();

如你所料,首先执行函数 first,然后执行函数 second——将以下内容记录到控制台:
// 1
// 2

但如果函数 first 包含某种无法立即执行的代码呢?比如有个 API 请求,我们必须发送请求然后等待响应?为了模拟这个操作,我们使用 JavaScript 函数 setTimeout,它会在一段时间后调用一个函数。我们将函数延迟 500 毫秒来模拟 API 请求。我们的新代码如下所示:

function first(){
  // 模拟代码延迟
  setTimeout( function(){
    console.log(1);
  }, 500 );
}
function second(){
  console.log(2);
}
first();
second();

当前理解 setTimeout() 是如何工作的并不重要,重要的是你看到我们已经移动了 console.log(1);在我们 500 毫秒的延迟之内。那么现在我们调用函数会发生什么呢?
first();
second();
// 2
// 1

虽然我们首先调用 first() 函数,我们还是会在 second() 函数之后注销该函数的结果。
并不是 JavaScript 没有按照我们想要的顺序执行我们的函数,而是在继续执行 second() 之前, JavaScript 没有等待 first() 的响应。

例如ajax请求都是异步的。请求发出去后,处理器会继续执行下面的代码。如果你想ajax请求完成后,做一些事情,显然,直接在下一行写代码是达不到目的。因为ajax请求,它是非阻塞式的,执行到ajax请求的语句不会停下来等请求完成再执行之后的语句。回调就是一种方法,帮我们确保某些代码直到另一些代码已经执行完毕后才执行。

你可能感兴趣的:(javascript)