理解javascript中的回调函数(callback)


Posted in Javascript onSeptember 02, 2014

最近在看 express,满眼看去,到处是以函数作为参数的回调函数的使用。如果这个概念理解不了,nodejs、express 的代码就会看得一塌糊涂。比如:

app.use(function(req, res, next) {

    var err = new Error('Not Found');

    err.status = 404;

    next(err);

});

app是对象,use是方法,方法的参数是一个带参的匿名函数,函数体直接在后面给出了。这段代码怎么理解呢?我们先来了解回调函数这个概念。
首先要了解,在 js 中,函数也是对象,可以赋值给变量,可以作为参数放在函数的参数列表中。比如:
var doSomething = function(a,b)

{

 return a + b;

}

这段代码的意思是定义一个匿名函数,这个匿名函数除了没有名字之外,其他跟普通的函数没有什么两样。然后把匿名函数赋值给变量doSomething。接下来我们调用:
console.log(doSomething(2,3));

这样会输出5。

回调函数,就是放在另外一个函数(如 parent)的参数列表中,作为参数传递给这个 parent,然后在 parent 函数体的某个位置执行。说来抽象,看例子:

// To illustrate the concept of callback

var doit = function(callback)

{

    var a = 1,

        b = 2,

        c = 3;

    var t = callback(a,b,c);

    return t + 10;

};

var d = doit(function(x,y,z){

    return (x+y+z);

});

console.log(d);

先定义 doit 函数,有一个参数 callback。这个 callback 就是回调函数,名字可以任意取。看函数体,先定义三个变量 a,b,c。然后调用 callback 函数。最后返回一个值。

下面就调用 doit 函数了。要注意的是,刚才定义 doit 时,callback 并没有定义,所以刚才并不知道 callback 是干什么用的。这其实很好理解,我们平时定义函数的时候,参数也只是给出了一个名字,比如 a,在函数体中使用 a,但整个过程也并不知道 a 到底是什么,只有在调用那个函数的时候才指定 a 的具体值,比如2.回过头来,在调用 doit 的时候,我们就需要指定 callback 究竟是个什么东西了。可以看到,这个函数完成了一个 sum 功能。

上述代码的执行过程是:

调用 doit函数,参数是一个匿名函数;进入 doit 的函数体中,先定义 a,b,c,然后执行刚才的匿名函数,参数是 a,b,c,并返回一个 t,最后返回一个 t+10给 d。

回到最初的例子,app.use(...)是函数调用。我们可以想象,之前一定定义了一个 use 方法,只是这里没有给出。这两个例子一对比,就可以马上理解了。

在使用nodejs、express 的时候,不可能每个方法或函数我们都要找到它的函数定义去看一看。所以只要知道那个定义里面给 callback 传递了什么参数就行了。然后在调用方法或函数时,在参数里我们自己定义匿名函数来完成某些功能。

Over!

Javascript 相关文章推荐
jQuery 1.3 和 Validation 验证插件1.5.1
Jul 09 Javascript
clientX,pageX,offsetX,x,layerX,screenX,offsetLeft区别分析
Mar 12 Javascript
jQuery 表单验证扩展代码(二)
Oct 20 Javascript
javascript 三种方法实现获得和设置以及移除元素属性
Mar 20 Javascript
如何学习Javascript入门指导
Nov 01 Javascript
深入解析JavaScript中函数的Currying柯里化
Mar 19 Javascript
AngularJS入门教程之MVC架构实例分析
Nov 01 Javascript
Bootstrap中datetimepicker使用小结
Dec 28 Javascript
关于meta viewport中target-densitydpi属性详解(推荐)
Aug 18 Javascript
vue项目上传Github预览的实现示例
Nov 06 Javascript
Makefile/cmake/node-gyp中区分判断不同平台的方法
Dec 18 Javascript
vue微信分享的实现(在当前页面分享其他页面)
Apr 16 Javascript
详解js闭包
Sep 02 #Javascript
jquery delay()介绍及使用指南
Sep 02 #Javascript
使用jquery实现放大镜效果
Sep 02 #Javascript
javascript初学者常用技巧
Sep 02 #Javascript
js/jquery判断浏览器的方法小结
Sep 02 #Javascript
Iframe实现跨浏览器自适应高度解决方法
Sep 02 #Javascript
jQuery级联操作绑定事件实例
Sep 02 #Javascript
You might like
PHP+DBM的同学录程序(3)
2006/10/09 PHP
ThinkPHP调用common/common.php函数提示错误function undefined的解决方法
2014/08/25 PHP
PHP登录验证码的实现与使用方法
2016/07/07 PHP
jquery tab标签页的制作
2010/05/10 Javascript
Array的push与unshift方法性能比较分析
2011/03/05 Javascript
关于JS管理作用域的问题
2013/04/10 Javascript
js中widow.open()方法使用详解
2013/07/30 Javascript
jQuery中获取checkbox选中项等操作及注意事项
2013/11/24 Javascript
JavaScript截取字符串的2个函数介绍
2014/08/27 Javascript
JavaScript使用replace函数替换字符串的方法
2015/04/06 Javascript
JavaScript实现的encode64加密算法实例分析
2015/04/15 Javascript
BootStrap智能表单实战系列(七)验证的支持
2016/06/13 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
2016/08/03 Javascript
Node.js与Sails redis组件的使用教程
2017/02/14 Javascript
详谈表单重复提交的三种情况及解决方法
2017/08/16 Javascript
javascript基础进阶_深入剖析执行环境及作用域链
2017/09/05 Javascript
在 Vue 中编写 SVG 图标组件的方法
2020/02/24 Javascript
[01:38]DOTA2第二届亚洲邀请赛中国区预选赛出线战队晋级之路
2017/01/17 DOTA
python获取文件版本信息、公司名和产品名的方法
2014/10/05 Python
python密码错误三次锁定(实例讲解)
2017/11/14 Python
详解如何使用Python编写vim插件
2017/11/28 Python
将python文件打包成EXE应用程序的方法
2019/05/22 Python
Python3 main函数使用sys.argv传入多个参数的实现
2019/12/25 Python
浅谈keras 的抽象后端(from keras import backend as K)
2020/06/16 Python
MAC Cosmetics巴西官方网站:M·A·C彩妆
2019/04/18 全球购物
出纳的岗位职责
2013/11/09 职场文书
节约用水的口号
2014/06/20 职场文书
政府班子四风问题整改措施思想汇报
2014/10/08 职场文书
2014年安全工作总结范文
2014/11/13 职场文书
慰问信格式
2015/02/14 职场文书
医药公司开票员岗位职责
2015/04/15 职场文书
飞越疯人院观后感
2015/06/09 职场文书
2016大学军训通讯稿
2015/11/25 职场文书
用人单位的规章制度,怎样制定才是有效的?
2019/07/09 职场文书
《钢铁是怎样炼成的》高中读后感
2019/08/07 职场文书
详解Java实践之抽象工厂模式
2021/06/18 Java/Android