刚开始学习javascript时,对回调函数的理解仅仅停留在知道定义阶段。什么是回调函数? 就是将一个函数做为参数传递给另外一个函数,做为参数的这个函数就是回调函数。 至于为何要用到回调函数?回调函数有什么做用? 当时对这些一无所知! 最近学习node.js涉及到了大量的异步编程,不少地方都须要用到回调函数,因此这两天深刻了解了JavaScript的回调函数,下面是我对回调函数的理解。javascript
想要弄明白js回调函数,首先要清楚函数的规则,在javascript中函数是一个对象,准确的来讲函数是用function()构造函数建立的一个function对象,所以咱们能够将函数存储在变量中,固然也就能够将存储在变量中的函数做为一个参数传递给另外一个函数,这就是回调函数。
举个例子:html
var callback = function(arg3) { console.log('callback Totle is:' + arg3) } function fn(arg1, arg2, cb) { var Total = arg1 + arg2; cb(Total); console.log('mainFunction Totle is:' + Total) } fn(2, 2, callback) // 调用fn()函数,并传入2, 2, callback做为参数
上面例子中咱们将一个匿名函数赋值给变量callback,同时将callback做为参数传递给了fn()函数,这时在函数fn()中callback就是回调函数。java
上面的代码执行结果为:node
callback Totle is:4 mainFunction Totle is:4
不对啊! 回调函数不是应该在主函数的最后执行吗?
对,不少介绍回调函数的例子讲到这里是就完了,异步回调函数的确是应该在函数的最后执行,不过上面的例子是一个同步回调函数,函数的执行顺序依然自上而下顺序执行。 那么什么是异步回调呢? 咱们又怎么实现异步回调呢? 下面咱们举两个例子来讲明:编程
示例1:网络
function f2() { console.log('f2 finished') } function f1(cb) { setTimeout(cb,1000) //用setTimeout()模拟耗时操做 console.log('f1 finished') } f1(f2); //获得的结果是 f1 finished ,f2 finished
这里咱们用setTimeout()来模拟耗时操做的前提是js中的setTimeout()函数支持异步处理,因此咱们获得的结果是 f1 finished ,f2 finishedapp
示例2:异步
var fs = require("fs"); fs.readFile('input.txt','utf-8', function (err, data) { if (err) return console.error(err); console.log(data.toString()); }); console.log("程序执行结束!");
程序执行的结果是:async
$ node app 程序执行结束! 咱们来测试一下异步回调函数
上面例子中咱们先建立了一个文件input.txt,里面的内容是:'咱们来测试一下异步回调函数'
若是按照同步的思惟,程序应该执行fs.readFile,直到文件读完以后才执行后面的console.log("程序执行结束!"); 然而node中的fs.readFile是支持异步处理的,所以程序执行到这儿的时候并不会阻塞,而是继续向后执行,当文件读取完毕以后再自动调用传入的匿名回调函数,所以出现了上面的结果。异步编程
参考文章:
详解回调函数——以JS为例解读异步、回调和EventLoop http://blog.csdn.net/tywinsta...
Javascript异步编程的4种方法 - 阮一峰的网络日志http://www.ruanyifeng.com/blo...