JavaScript:什么是回调?
翻译练习
在6分钟内通过简单的例子学习和理解回调的基本原理。
什么是回调?
简单地说:回调就是一个在另一个函数执行完成后再去执行的函数--因此得名回调。
复杂点讲:在JavaScript中,函数是对象。因此,函数可以把其他函数当做参数,也可以被其他函数返回。这样做的函数称为高阶函数。任何被当做参数传递的函数都叫回调函数。
上面已经讲了很多,让我们通过一些例子把这些去细化一下。
为什么我们需要回调?
有一条非常重要的原因:JavaScript是一门事件驱动的语言。这意味着,JavaScript在监听其他事件的同时会继续执行,而不是在继续执行之前去等待响应。
function first(){
console.log(1);
}
function second(){
console.log(2);
}
first();
second();
正如你期望的那样,函数first
会首先执行,函数second
会接着执行--控制台打印如下:
// 1
// 2
目前看来一切良好。
但是,如果函数first
包含一些不会立即执行的代码会发生什么呢?比如说,一个API请求,我们必须去发送请求然后等待响应吗?为了模拟这种动作,我们使用setTimeout
--在JavaScript
中,这个函数将会在设定的一段时间后去调用一个函数。我们来把我们的函数延迟500ms去模拟一个API请求。我们的新代码像下面这样:
function first(){
// Simulate a code delay
setTimeout( function(){
console.log(1);
}, 500 );
}
function second(){
console.log(2);
}
first();
second();
现在你理不理解setTimeout()
怎么工作的并不重要。现在最重要的是,你看我们把console.log(1);
移动到500ms的延时中。那么,我们现在执行代码会发生什么呢?
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.
现在,让我们来添加回调--作为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
作为参数传给了它。
现实世界的例子
上周我发布了一篇文章,这篇文章中代码运行的唯一原因就是Twitters API。当你对一个API发起请求时,你必须等到它响应才能对相应进行操作。这是一个现实生活中关于回调的完美例子。下面是这个请求的代码:
T.get('search/tweets', params, function(err, data, response) {
if(!err){
// This is where the magic will happen
} else {
console.log(err);
}
})
T.get
仅仅表示我们在向Twitter发起一个get请求。- 在
search/tweets
请求中有三个参数,分别是:请求的路由、查询的参数param和我们的回调--一个匿名函数。
回调在这里很重要,因为在运行到后面的代码之前,我们需要先从服务器获取到响应。我们不知道在我们讲参数通过get请求发送到search/tweets
后我们的API请求成功与否,我们只能等着。一旦Twitter做出响应,我们的回调函数就会被调用。Twitter要么返回一个错误信息给我们,或者返回响应对象给我们。在我们的回调函数中,我们可以通过if()
语句去确定我们的请求是成功了还是失败了,然后相应地对新数据做出处理。
你做到了
干得不错。理想情况下,你现在已经理解了什么是回调还有它是怎么工作的。这仅仅是回调的冰山一角,还有很多你需要去学习。我每周会发布了一些文章/教程,如果你想被加入到我的once-weekly邮箱列表,在这里了输入你的邮箱吧。
JavaScript:什么是回调?的更多相关文章
- 理解和使用 JavaScript 中的回调函数
理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报 分类: JavaScript(4) 目录( ...
- JavaScript——callback(回调函数
1.回调函数定义 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直 ...
- [转]理解与使用Javascript中的回调函数
在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...
- 【JavaScript】理解与使用Javascript中的回调函数
在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...
- Javascript class获取回调函数数据
/********************************************************************** * Javascript class获取回调函数数据 * ...
- JavaScript callback function 回调函数的理解
来源于:http://mao.li/javascript/javascript-callback-function/ 看到segmentfault上的这个问题 JavaScript 回调函数怎么理解, ...
- 理解javascript中的回调函数(callback)【转】
在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...
- JavaScript 中的回调函数
原文:http://javascriptissexy.com/ 翻译:http://blog.csdn.net/luoweifu/article/details/41466537 [建议阅读原文,以下 ...
- JavaScript系列之回调函数callback
JavaScript系列之回调函数callback JavaScript回调函数的使用是很常见的,引用官方回调函数的定义: A callback is a function that is passe ...
- 理解与使用Javascript中的回调函数 -2
在javascript中回调函数非常重要,它们几乎无处不在.像其他更加传统的编程语言都有回调函数概念,但是非常奇怪的是,完完整整谈论回调函数的在线教程比较少,倒是有一堆关于call()和apply() ...
随机推荐
- 数理统计7:矩法估计(MM)、极大似然估计(MLE),定时截尾实验
在上一篇文章的最后,我们指出,参数估计是不可能穷尽讨论的,要想对各种各样的参数作出估计,就需要一定的参数估计方法.今天我们将讨论常用的点估计方法:矩估计.极大似然估计,它们各有优劣,但都很重要.由于本 ...
- Educational Codeforces Round 97 (Rated for Div. 2) E. Make It Increasing(最长非下降子序列)
题目链接:https://codeforces.com/contest/1437/problem/E 题意 给出一个大小为 \(n\) 的数组 \(a\) 和一个下标数组 \(b\),每次操作可以选择 ...
- Atcoder Beginner Contest 168 D - .. (Double Dots) (BFS)
题意:有\(n\)个房间,在这些房间中两两连\(m\)次条边,问除了第一个房间,其他房间走到第一个房间的最短路径,输出这个房间所连的上一个房间,如果走不到,输出\(no\). 题解:刚开始我写了一个d ...
- 如何加入VNT Hubble主网
环境:Ubuntu20.04 (但以下方法应该只要不是过于老旧的Ubuntu,都行得通) 从源码安装go-vnt 安装Go编译器(版本大于1.9)和C编译器 安装C编译器GCC[1] sudo apt ...
- woj1018(HDU4384)KING KONG 循环群
title: woj1018(HDU4384)KING KONG 循环群 date: 2020-03-19 09:43:00 categories: [acm] tags: [acm,woj,数学] ...
- codeforces 1009D Relatively Prime Graph【欧拉函数】
题目:戳这里 题意:要求构成有n个点,m条边的无向图,满足每条边上的两点互质. 解题思路: 显然1~n这n个点能构成边的条数,就是2~n欧拉函数之和(x的欧拉函数值代表小于x且与x互质的数的个数. 因 ...
- 牛客网多校第4场 J Hash Function 【思维+并查集建边】
题目链接:戳这里 学习博客:戳这里 题意: 有n个空位,给一个数x,如果x%n位数空的,就把x放上去,如果不是空的,就看(x+1)%n是不是空的. 现在给一个已经放过数的状态,求放数字的顺序.(要求字 ...
- 牛客网-Beautiful Land 【01背包 + 思维】
链接:https://www.nowcoder.com/acm/contest/119/F来源:牛客网 Now HUST got a big land whose capacity is C to p ...
- POJ 2923 Relocation(状压DP)题解
题意:有2辆车运货,每次同时出发,n(<10),各自装货容量c1 c2,问最少运几次运完. 思路:n比较小,打表打出所有能运的组合方式,用背包求出是否能一次运走.然后状压DP运的顺序. 代码: ...
- UA 广告 All In One
UA 广告 All In One UA 广告是什么 广告投放 / 市场营销 互联网营销和分析专用名词速览 http://www.chinawebanalytics.cn/digital-marketi ...