探讨nodejs回调函数的执行顺序与回调函数的参数是哪儿来的

console.log('2--------------------')
//fs.readFile(file[, options], callback)

//默认获取二进制数据。参数设置为utf8将获取文本数据
fs.readFile('w.js', 'utf8', function (err, data) {
    if (err) throw err;
    console.log(arguments);
});
//---------------------
console.log('3FileList--------------------')
//fs.readFileSync(file[, options])
//file 不是文件夹,而是文件。

let fileList = fs.readFileSync('w.js','utf8');
console.log(fileList);

//通过2和3的执行结果,回调函数会在3执行完毕之后在执行, 探讨nodejs回调函数的执行顺序。
//Node.js回调
//Node.js 异步编程依托于回调来实现。
//Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。
//回调函数在完成任务后就会被调用,
//例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。
// 这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求。

//1、阻塞代码实例
//创建一个文件 test.txt ,内容如下:
//Hello World!
//fs.readFileSync()
//fs.readFile()

//创建 test.js 文件, 代码如下:
console.log('-------阻塞程序开始执行--------');
// 引入fs模块
var fs = require("fs");
//同步读取文件
var data = fs.readFileSync('test.txt','utf-8');
console.log(data.toString());
console.log('-------阻塞程序执行结束--------');

//执行结果:
//-------阻塞程序开始执行--------
//Hello World!
//fs.readFileSync()
//fs.readFile()
//-------阻塞程序执行结束--------


//2、非阻塞代码实例
//创建 test.js 文件, 代码如下:
console.log('-------非阻塞程序开始执行--------');
// 引入fs模块
var fs = require("fs");
//异步读取文件
fs.readFile('test.txt','utf-8',function (err, data) {
    if (err) return console.error(err);
    console.log(data.toString());
});
console.log('-------非阻塞程序执行结束--------');

//执行结果:
//-------非阻塞程序开始执行--------
//-------非阻塞程序执行结束--------
//Hello World!
//fs.readFileSync()
//fs.readFile()

//fs.readFile() 是异步函数用于读取文件。如果在读取文件过程中发生错误,错误 err 对象就会输出错误信息。
// 如果没发生错误,readFile 跳过 err 对象的输出,文件内容就通过回调函数输出。

第一个实例在文件读取完后才执行完程序。第二个实例我们不需要等待文件读取完,这样就可以在读取文件时同时执行接下来的代码,大大提高了程序的性能。因此,阻塞按是按顺序执行的,而非阻塞是不需要按顺序的,所以如果需要处理回调函数的参数,我们就需要写在回调函数内。

ps: 观察者模式(事件处理): 只要触发了,立刻执行,非阻塞。

三、fs.readFileSync和fs.readFile函数用法。


1、s.readFileSync

语法:fs.readFileSync(filename, [encoding]) 

接收参数:

  filename:文件路径

  options:option对象,包含 encoding,编码格式,该项是可选的。

 由于Node.js仅支持如下编码:utf8, ucs2, ascii, binary, base64, hex,并不支持中文GBK或GB2312之类的编码,因此如果要读写GBK或GB2312格式的文件的中文内容,必须要用额外的模块:iconv-lite。

2、fs.readFile

语法:fs.readFile(filename, [encoding], [callback(err,data)])

接收参数:

  filename:文件路径

  options :option对象,包含 encoding,编码格式,该项是可选的。

  callback :回调,传递2个参数 异常err 和 文件内容 data

//关于回调函数:转自:https://blog.csdn.net/lixiaohaohao/article/details/81608177
刚开始入坑node.js,花了一下午才搞清楚什么是回调函数。回调函数是作为参数传递给另一个函数的,比如说function human(man,callback),这里的callback就是回调函数,看了很多篇文章有一句话给我留下了很深的印象就是
一般函数的形参是由外往内向函数体传递变量的入口,但是加入了callback后,就是指在完成函数体的操作后向外传递参数的入口。
也就是说,callback函数在当前函数完成之后才会被调用的,那么有人可能会问了,这不就阻塞了吗?一个函数在另一个函数之后调用不就是阻塞了吗,这个问题我也思考过,我的解释是这样的。由于js是异步的,也就是说每执行一个函数的时候不会将里面的代码执行完再执行下一个函数,而是会接着马上执行下一个函数,如果碰见了带有回调函数的函数的时候就会将回调函数入队列,这样将所有回调函数入队列后,等所有代码体执行完成后再将回调函数一个个取出来执行,这样就是异步非阻塞了。我还有一个理解就是,非阻塞是相对于io的,是非阻塞io也就是说当程序遇见需要执行io文件的时候就将io文件的执行交出去,将回调函数入队列,然后等io操作执行完成之后再将结果返回回调函数出队列,这也就是非阻塞io。至于但单线程,看到比较好的解释是,食堂只开放一个窗口,只有一个服务生,来点餐的人只需要告诉服务生他需要什么,然后服务生告诉厨师要做什么,然后马上下一位客人点餐,这样循环,客人不需要等上一位客人拿到他的事物后再点餐,效率提高了,就是服务生太惨了,需要一直不休息地服务,可能会过劳死,所以单线程不适用于大规模的集成计算

你可能感兴趣的:(探讨nodejs回调函数的执行顺序与回调函数的参数是哪儿来的)