JavaScript:回调是什么

回调是什么?

简单讲:回调是指在另一个函数执行完成 之后 被调用的函数 —— 因此得名“回调”。

稍复杂地讲:在 JavaScript 中,函数也是对象。因此,函数可以传入函数作为参数,也可以被其他函数返回。这样的函数称为 高阶函数 。被作为参数传入的函数就叫做 回调函数

^ 这听起来有点啰唆,让我们来看一些例子来简化一下。

为什么我们需要回调?

有一个非常重要的原因 —— JavaScript 是事件驱动的语言。这意味着,JavaScript 不会因为要等待一个响应而停止当前运行,而是在监听其他事件时继续执行。来看一个基本的例子:

JavaScript:回调是什么

正如你所料, first 函数首先被执行,随后 second 被执行 —— 控制台输出下面内容:

一切都如此美好。

但如果函数 first 包含某种不能立即执行的代码会如何呢?例如我们必须发送请求然后等待响应的 API 请求?为了模拟这种状况,我们将使用 setTimeout ,它是一个在一段时间之后调用函数的 JavaScript 函数。我们将函数延迟 500 毫秒来模拟一个 API 请求,新代码长这样:

JavaScript:回调是什么

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

JavaScript:回调是什么

即使我们首先调用了 first() 函数,我们记录的输出结果却在 second() 函数之后。

这不是 JavaScript 没有按照我们想要的顺序执行函数的问题,而是 JavaScript 在继续向下执行second() 之前没有等待 first() 响应 的问题。

所以为什么给你看这个?因为你不能一个接一个地调用函数并希望它们按照正确的顺序执行。回调正是确保一段代码执行完毕之后再执行另一段代码的方式。

创建一个回调

好了,说了这么多,让我们创建一个回调!

首先,打开你的 Chrome 开发者工具( Windows: Ctrl + Shift + J )( Mac: Cmd + Option + J),在控制台输入下面的函数声明:

function doHomework(subject) {

上面,我们已经创建了 doHomework 函数。我们的函数携带一个变量,是我们正在研究的课题。在控制台输入下面内容调用你的函数:

doHomework('math'); // Alerts: Starting my math homework.

现在把我们的回调加进来,我们传入 callback 作为 doHomework() 的最后一个参数。这个回调函数是我们定义在接下来要调用的 doHomework() 函数的第二个参数。

JavaScript:回调是什么

如你所见,如果你将上面的代码输入控制台,你将依次得到两个警告:第一个是“starting homework”,接着是“finished homework”。

但是你的回调函数并不总是必须定义在函数调用里面,它们也可以定义在你代码中的其他位置,比如这样:

JavaScript:回调是什么

这个例子的结果和之前的例子完全一致。如你所见,我们在 doHomework() 函数调用中传入了alertFinished 函数定义作为参数!

实际应用案例

有一篇关于构建一个 Twitter 机器人 的文章。文中的代码可以实现的唯一原因就是使用了Twitters API。当你向一个 API 发送请求,在你操作响应内容之前你必须等待这个响应。这是回调在实际应用中的绝佳案例。请求长这样:

JavaScript:回调是什么

1.T.get仅仅意味着我们将要向 Twitter 发送一个 get 请求

2.这个请求中有三个参数: ‘search/tweets’是请求的路径, params是搜索参数,随后的一个匿名函数是我们的回调。

回调在这里很重要,因为在我们的代码继续运行之前我们需要等待一个来自服务端的响应。我们并不知道 API 请求会成功还是会失败,所以通过 get 向 search/tweets 发送了请求参数以后,我们要等待。一旦 Twitter 响应,我们的回调函数就被调用。Twitter 要么发送一个 err(error)对象,要么发送一个 response对象返回给我们。在我们的回调函数中我们可以使用 if()语句来区分请求是否成功,然后相应地处理新数据。

你做到了

干得漂亮!你现在(理想状况下)已经理解了回调是什么,回调如何工作。这只是回调的冰山一角,记住学无止境啊!

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: