前言
说到回调函数,可能大家都会想到异步编程的首选解决方案 9102,更多的异步编程方案层出不穷,典型的代表就是 promise ,async await 不扯远了,回到NodeJs
。
Node.js 异步编程的直接体现就是回调,回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。
例如:我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回,这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求
。
这里边有一个关键词 I/O
, 说到 I/O
很多童鞋可能不太理解什么是 I/O
,I/O
其实是 输入/输出(Input/Output)
,可自行百度百科一下,从这里再说到同步I/O,异步I/O 可能大家就能明白了。
- 同步
I/O
阻塞 , 同步输入输出 - 异步
I/O
不阻塞, 异步输入输出
如果有童鞋不太理解同步/异步这个问题,建议自行学习一下哈 ~
回归正题,回调函数
一般,回调函数作为函数的最后一个参数出现,例如:
function foo(name, age, callback) { }
// callback 就是回调函数
我们来通过同步I/O,异步I/O实例来实践一下:
创建一个阻塞的同步I/O实例
input.txt 内容: hello 回调函数
这里的 fs 是nodeJs 的文件系统模块儿 fs.readFileSync
是同步读取文件内容,fs 后边会讲到。
// callback.js 内容
var fs = require("fs");
var data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("程序运行结束!");
这里涉及到如何运行 nodeJs 文件,我们简单说一下,就是在项目工程根目录创建一个xx.js
文件,然后在根目录运行 node xx.js
文件即可,例子:
目录: PS C:\HiSen\myWorkDemo\node_demo>
运行命令:node callback.js
callback.js // 如上代码内容
input.txt // 如上内容
运行命令
PS C:\HiSen\myWorkDemo\node_demo> node callback.js
hello 回调函数
程序运行完毕
PS C:\HiSen\myWorkDemo\node_demo>
很清楚的可以看到,我们打印了
hello 回调函数
程序运行完毕
按照Js单线程,自上而下执行,依次打印结果。
那我们来一个非堵塞异步I/O实例
同样的结构,我们只用修改一下 callback.js
的文件读取方式,如下:
fs.readFile 异步读取文件内容
, 回调函数有两个参数
1,error 错误,异常
2,成功回调结果
var fs = require("fs");
fs.readFile("input.txt", function (err, res) {
console.log(res.toString())
});
// console.log(data.toString()) // 同步试验
console.log("程序运行完毕")
同样运行程序 node callback.js
, 发现先打印程序运行完毕,再打印 hello 回调函数 。
PS C:\HiSen\myWorkDemo\node_demo> node callback.js
程序运行完毕
hello 回调函数
PS C:\HiSen\myWorkDemo\node_demo>
结论:
- 通过同步I/O,异步I/O来认识了回调函数和实践
- 同步I/O,堵塞
- 异步I/O,不堵塞,大大提高了程序的性能