回调函数
回调函数,也被称为高阶函数,是一个函数被作为参数传递给另一个函数。(主要搞Java,第一次见这个概念。)
函数也是对象
在javascript中,函数是对象。确切地说,函数是用Function()构造函数创建的Function对象。Function对象包含一个字符串,字符串包含函数的javascript代码。
//可以这样创建函数 var fn = new Function("arg1", "arg2", "return arg1 * arg2;"); fn(2, 3); //6
传递函数作为回调
在下面的例子中,将一个匿名函数当作参数传递给了fn函数。
function fn(arg1, arg2, callback){ var num = Math.ceil(Math.random() * (arg1 - arg2) + arg2); callback(num); //传递结果 } fn(10, 20, function(num){ console.log("Callback called! Num: " + num); }); //结果为10和20之间的随机数
这种机制在jquery中经常可以见到。
$("#btn_1").click(function() { alert("Btn 1 Clicked"); });
为什么要用回调函数
传统函数以参数形式输入数据,并且使用返回语句返回值。理论上,在函数结尾处有一个return返回语句,结构上就是:一个输入点和一个输出点。这比较容易理解,函数本质上就是输入和输出之间实现过程的映射。
但是,当函数的实现过程非常漫长,是选择等待函数完成处理,还是使用回调函数进行异步处理呢?这种情况下,使用回调函数变得至关重要,例如:AJAX请求。若是使用回调函数进行处理,代码就可以继续进行其他任务,而无需空等。实际开发中,经常在javascript中使用异步调用。
Node.js 回调函数
Node.js 异步编程的直接体现就是回调。
异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。
回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。
阻塞代码实例
创建一个input.txt文件(用英文,免得乱码):
If life knocks you down, don't worry, don't fell sad , it will knock Ground and Pound.
创建main.js,读取文件:
var fs=require("fs"); var data = fs.readFileSync('input.txt'); console.log(data.toString()); console.log("程序执行结束");
运行一下:
非阻塞实例
mainb.js:
var fs = require("fs"); fs.readFile('input.txt', function (err, data) { if (err) return console.error(err); console.log(data.toString()); }); console.log("程序执行结束!");
运行一下:
可以看到,阻塞实例是按照顺序执行的,而非阻塞实例不是按照顺序执行的。
第一个实例在文件读取完后才执行完程序。 第二个实例我们不需要等待文件读取完,这样就可以在读取文件时同时执行接下来的代码,大大提高了程序的性能。
如果想需要处理回调函数的参数,我们就需要写在回调函数内。
参考:
【1】、https://www.runoob.com/nodejs/nodejs-callback.html
【2】、https://www.jb51.net/article/54750.htm
【3】、https://www.w3cschool.cn/nodejs/nodejs-callback.html