理解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 相关文章推荐
20个非常棒的Jquery实用工具 国外文章
Jan 01 Javascript
在子窗口中关闭父窗口的一句代码
Oct 21 Javascript
浅谈JavaScript函数参数的可修改性问题
Dec 05 Javascript
简体中文转换繁体中文(实现代码)
Dec 25 Javascript
js保留小数点后几位的写法
Jan 03 Javascript
基于MVC4+EasyUI的Web开发框架形成之旅之界面控件的使用
Dec 16 Javascript
jQuery中的Deferred和promise 的区别
Apr 03 Javascript
概述VUE2.0不可忽视的很多变化
Sep 25 Javascript
微信小程序(应用号)开发新闻客户端实例
Oct 24 Javascript
详解vue过滤器在v2.0版本用法
Jun 01 Javascript
JavaScript实现快速排序的方法分析
Jan 10 Javascript
antd vue table跨行合并单元格,并且自定义内容实例
Oct 28 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 URL验证正则表达式
2011/07/19 PHP
php中判断字符串是否全是中文或含有中文的实现代码
2011/09/16 PHP
PHP经典面试题集锦
2015/03/19 PHP
yii2框架中使用下拉菜单的自动搜索yii-widget-select2实例分析
2016/01/09 PHP
php基于jquery的ajax技术传递json数据简单实例
2016/04/15 PHP
PHP中include/require/include_once/require_once使用心得
2016/08/28 PHP
[原创]PHP正则删除html代码中a标签并保留标签内容的方法
2017/05/23 PHP
PHP5.5新特性之yield理解与用法实例分析
2019/01/11 PHP
PHP单例模式数据库连接类与页面静态化实现方法
2019/03/20 PHP
PHP 8新特性简介
2020/08/18 PHP
Aster vs KG BO3 第二场2.19
2021/03/10 DOTA
xml分页+ajax请求数据源+dom取结果实例代码
2008/10/31 Javascript
数组Array进行原型prototype扩展后带来的for in遍历问题
2010/02/07 Javascript
一个基于jquery的图片切换效果
2010/07/06 Javascript
jQuery的实现原理的模拟代码 -1 核心部分
2010/08/01 Javascript
javascript attachEvent绑定多个事件执行顺序问题
2010/10/20 Javascript
JS上传图片前的限制包括(jpg jpg gif及大小高宽)等
2012/12/19 Javascript
js弹出层(jQuery插件形式附带reLoad功能)
2013/04/12 Javascript
JavaScript中定义函数的三种方法
2015/03/12 Javascript
jquery实现Slide Out Navigation滑出式菜单效果代码
2015/09/07 Javascript
JavaScript跨域调用基于JSON的RESTful API
2016/07/09 Javascript
JS控制HTML元素的显示和隐藏的两种方法
2016/09/27 Javascript
脚本div实现拖放功能(两种)
2017/02/13 Javascript
基于vue-upload-component封装一个图片上传组件的示例
2018/10/16 Javascript
javascript json字符串到json对象转义问题
2019/01/22 Javascript
JavaScript 链表定义与使用方法示例
2020/04/28 Javascript
vue 获取元素额外生成的data-v-xxx操作
2020/09/09 Javascript
js加减乘除精确运算方法实例代码
2021/01/17 Javascript
[46:55]Ti4 冒泡赛第二轮 LGD vs C9
2014/07/14 DOTA
python将处理好的图像保存到指定目录下的方法
2019/01/10 Python
Pycharm如何打断点的方法步骤
2019/06/13 Python
使用pyhon绘图比较两个手机屏幕大小(实例代码)
2020/01/03 Python
Python requests模块session代码实例
2020/04/14 Python
入党申请人的自我鉴定
2013/12/01 职场文书
个人作风建设自查报告
2014/10/22 职场文书
2015年团支书工作总结
2015/04/03 职场文书