[译] JavaScript:回调是什么鬼?
发布日期:2021-08-25 15:35:26 浏览次数:13 分类:技术文章

本文共 2828 字,大约阅读时间需要 9 分钟。

  • 原文地址:
  • 原文作者:
  • 译文出自:
  • 译者:
  • 校对者:、

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

回调  —— 题图来自

回调是什么?

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

稍复杂地讲: 在 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 函数定义作为参数!

实际应用案例

上周我发表了一篇关于如何的文章。文中的代码可以实现的唯一原因就是我使用了 。当你向一个 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() 语句来区分请求是否成功,然后相应地处理新数据。

你做到了

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


是一个翻译优质互联网技术文章的社区,文章来源为 上的英文分享文章。内容覆盖 、、、、、、 等领域,想要查看更多优质译文请持续关注 。

转载地址:https://blog.csdn.net/weixin_33858336/article/details/88009400 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Node.js 的模块机制
下一篇:零基础学HTML5的学习路线完整版

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年03月16日 23时45分45秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

html5 调用摄像头 支持IE,JS调用本地摄像头拍照(兼容各大浏览器及IE8+) 2019-04-21
rust和gta5哪个吃配置_盘点4款Steam“自由度”很高的游戏,GTA5众所周知,目前最热门... 2019-04-21
es审计日志_elasticsearch 事务日志translog 2019-04-21
文件未找到mathpage.wll_解决MathPage.wll文件找不到的问题(找了好久的良心之作)... 2019-04-21
java 图片旋转保存_Java 对图片90度旋转 2019-04-21
用java实现文学研究助手_数据结构文学研究助手 C语言代码实现(带源码+解析)... 2019-04-21
java gc的几种方式_GC 的三种基本实现方式 2019-04-21
wget linux java 32_通过wget在Linux上下载Java JDK会显示在许可证页面上 2019-04-21
babylonjs 设置面板位置_babylonjs 空间坐标转为屏幕坐标 2019-04-21
oracle里面如何查询sqlid,CSS_oracle中如何查看sql, --查询表状态:  select uo.O - phpStudy... 2019-04-21
php局部页面滚动,在访问另一页面后保留浏览器滚动位置 - php 2019-04-21
jmeter运行linux命令行,Jmeter在linux上运行(命令行运行Jmeter) 2019-04-21
linux服务器怎么添加站点,如何增加站点或虚拟主机及文件说明 2019-04-21
linux系统输入指令,Linux系统基础 - 基本操作命令 2019-04-21
mysql in 有序_mysql中的in排序 mysql按in中顺序来排序 2019-04-21
由于连接方在一段时间后没有正确答复或连接的主机_新风换气机使用效果不佳,为何?掌握正确使用方法就好了... 2019-04-21
mysql 查询姓王_MySQL查询语句练习题,测试足够用了 2019-04-21
mysql多实例脚本_mysql多实例脚本 2019-04-21
python如何生成excel文件夹_用python脚本通过excel生成文件夹树结构 2019-04-21
python获取post请求中的所有参数_Django从POST reques获取请求参数 2019-04-21