本文讲的是[译] JavaScript:回调是什么鬼?,

  • 原文地址:JavaScript: What the heck is a Callback?
  • 原文作者:Brandon Morelli
  • 译文出自:掘金翻译计划
  • 译者:sunui
  • 校对者:reid3290、wilsonandusa

配合简单的示例,用短短 6 分钟学习和理解回调的基本知识。

回调  —— 题图来自 unsplash

回调是什么?

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

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

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

为什么我们需要回调?

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

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

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

// 1
// 2

一切都如此美好。

但如果函数 first 包含某种不能立即执行的代码会如何呢?例如我们必须发送请求然后等待响应的 API 请求?为了模拟这种状况,我们将使用 setTimeout,它是一个在一段时间之后调用函数的 JavaScript 函数。我们将函数延迟 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 没有按照我们想要的顺序执行函数的问题,而是 JavaScript 在继续向下执行 second() 之前没有等待 first() 响应的问题。

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

创建一个回调

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

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

function doHomework(subject) {alert(`Starting my ${subject} homework.`);
}

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

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

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

function doHomework(subject**, callback**) {alert(`Starting my ${subject} homework.`);
**callback();**
}doHomework('math'**, function() {alert('Finished my homework');
}**);

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

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

function doHomework(subject, callback) {alert(`Starting my ${subject} homework.`);callback();
}function alertFinished(){alert('Finished my homework');
}**doHomework('math', alertFinished);**

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

实际应用案例

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

T.get('search/tweets', params, function(err, data, response) {if(!err){// 这里是施展魔法之处} else {console.log(err);}
})
  • T.get 仅仅意味着我们将要向 Twitter 发送一个 get 请求
  • 这个请求中有三个参数:‘search/tweets’ 是请求的路径,params 是搜索参数,随后的一个匿名函数是我们的回调。

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

你做到了

干得漂亮!你现在(理想状况下)已经理解了回调是什么,回调如何工作。这只是回调的冰山一角,记住学无止境啊!我每周都会更新一些文章/教程,如果你愿意接收每周一次的推送,点击这里输入你的邮箱订阅吧!





原文发布时间为:2017年6月22日

本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。

[译] JavaScript:回调是什么鬼?相关推荐

  1. javascript 回调函数

    javascript 回调函数 回调函数 作为参数传递的函数 示例代码 let x = function () {console.log("执行回调函数") }let y = fu ...

  2. [译] JavaScript 中的 CSS:基于组件的样式的未来

    本文讲的是[译] JavaScript 中的 CSS:基于组件的样式的未来, 原文地址:CSS in JavaScript: The future of component-based styling ...

  3. 理解javascript 回调函数

    理解javascript 回调函数 原文:理解javascript 回调函数 ##回调函数定义 百度百科:回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一 ...

  4. 使用Minions解释JavaScript回调

    by Kevin Kononenko 凯文·科诺年科(Kevin Kononenko) 使用Minions解释JavaScript回调 (JavaScript Callbacks Explained ...

  5. [译] JavaScript 的函数式编程是一种反模式

    本文讲的是[译] JavaScript 的函数式编程是一种反模式, 原文地址:Functional programming in JavaScript is an antipattern 原文作者:A ...

  6. [译]JavaScript:更严格的相等

    原文:http://www.2ality.com/2012/03/stricter-equality.html 大部分JavaScript程序员都知道:应该使用严格相等(===)来代替"普通 ...

  7. javascript回调函数笔记

    来源于:https://github.com/useaname/blog-study 在Javascript中,函数是第一类对象.意味函数可以像对象一样按照第一类被管理使用. 回调函数是从一个叫函数式 ...

  8. JavaScript 回调(callback)函数

    此文适合JavaScript入门级选手阅读,高手就可以飘过了. 先扯点闲话.在中国,有这么一种现象:不管什么词或者概念,总会有些人把这些东西解释的神乎其神,貌似搞得别人听不懂就觉得自己很厉害的样子.其 ...

  9. javascript回调函数(模式)原理和示例深入分析

                                                                                     广大网友读懂了我之前论述的javasc ...

最新文章

  1. oracle11g安装过程提示swap size 检查失败问题
  2. Spring Boot 管理 MVC
  3. 浅谈async、await关键字 = 深谈async、await关键字
  4. 文件句柄(file handles) 文件描述符(file descriptors)
  5. sklearn朴素贝叶斯分类器_python机器学习:方法链和朴素贝叶斯分类器
  6. delete kubectl pod_kubectl delete
  7. systemctl的使用
  8. Mac电脑查看JDK文档,CHM格式文档阅读
  9. 江苏大学数字图像处理MATLAB人脸识别,MATLAB人脸识别代码
  10. 怎么在计算机中搜索可移动硬盘,为什么本地硬盘在计算机上显示为可移动硬盘...
  11. 固态硬盘替换机械硬盘
  12. Git之(一)Git是什么
  13. 期货开户公司想恶意滑点是做不到的
  14. opp原则_完美事业OPP与NDO纲要
  15. MMORPG摄像机操作
  16. 移动互联网应用的十项设计原则和小提示
  17. html中按钮下拉菜单,Bootstrap3.0学习笔记之按钮与下拉菜单
  18. 台积电认清了形势,新的建厂计划没有美国,中国芯片也得到重视
  19. 人工智能如何帮助水电实现可持续发展
  20. 课程设计1:简易洗衣机控制设计

热门文章

  1. asscess 一条记录更新数据_一条MySQL更新语句是怎么执行的?
  2. Python的for循环显示每个元素的下标
  3. nginx不缓存html页面耗性能,加速nginx性能: 开启gzip和缓存
  4. python的dropna 和notna的性能_python数据分析学习(7)数据清洗与准备(1)
  5. keil5函数 默认返回值_Excel等级判定,除了If函数外,还有5个易学易用易懂的技巧需要掌握!...
  6. 在树莓派3B+ 上使用YOLO v3 Tiny进行实时对象检测
  7. android 中xml文件的各种样式的学习
  8. 加密芯片在汽车无钥匙启动行业的应用
  9. “跨国视频造假窝点”曝光!这个大规模数据集,帮AI揪出99%换脸视频
  10. 真·干货!这套深度学习教程整理走红,从理论到实践的带你系统学习 | 资源...