Node.js开发指南——第3章安装Node.js快速入门(二) 异步式I/O

                                                                      Node.js最大的特点是异步式I/O(或者非阻塞I/O).
同步式I/O(阻塞式)
   异步式I/O(非阻塞式)
      利用多线程提供吞吐量
   通过事件片分割和线程调度利用多核CPU
   需要由操作系统调度多线程使用多核CPU
   难以充分利用CPU资源
   内存轨迹大,数据局部性弱
   符合线性的编程思维
单线程即可实现高吞吐量
通过功能划分利用多核CPU
可以将单进程绑定到单核CPU
可以充分利用CPU资源
内存轨迹小。数据局部性强
不符合传统编程思维
同步式I/O: 线程在执行中如果遇到磁盘读写或网络通信(统称为I/O操作),通常要耗费较长的时间,这时操作系统会剥夺这个线程的CPU控制权,使其暂停执行,同时将资源让给其他的工作线程,这种线程调度方式称为阻塞。当I/O操作完毕,操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行。这种I/O模式就是通常的同步式I/O(Synchronous I/O).
 
异步式I/O: 当线程遇到I/O操作时,不会以阻塞的方式等待I/O操作的完成或数据的返回,而只是将I/O请求发送到操作系统,继续执行下一条语句。当操作系统完成I/O操作时,以事件的形式通知执行I/O操作的线程,线程会在特定时候处理这个事件。为了处理异步I/O,线程必须有事件循环,不断地检查有没有未处理的事件,依次处理。
 
单线程事件驱动的异步式I/O比传统的多线程阻塞式I/O究竟好在哪里呢?异步式I/O就是少了多线程的开销。
异步式编程的缺点在于不符合人们一般的程序设计思维。不过可喜的是现在已经有了不少专门解决异步式编程问题的库(如async)
 
 
下面是关于Node.js如何用异步的方式读取一个文件的例子。
        先新建一个文本file.txt,因为我这里的内容是中文,这里就有个注意的地方。保存的txt默认编码是ANSI的,Node.js是读不出中文的,只认utf8编码。如果不是中文内容,不用改编码,直接保存就行。
       所以按我的方法来改编码:打开记事本新建一个空白的文本文档,不输入任何文字,然后保存此文档,在“另存为”对话框中将编码
由默认的 ANSI 修改为  UTF-8,接着为文件取名,在此将新文档命名为 file.txt。
      
然后写readfile.js
var fs = require('fs');
fs.readFile('file.txt','utf-8',function(err,data){
     if(err){
         console.error(err);
     }else{
         console.log(data);
     }
});
console.log('end.');
运行结果如下:

 从结果看出: end先被输出。这就是异步式I/O,通过回调函数来实现的。fs.readFile第一个参数是文件名,第二个参数是编码方式,第三个是一个函数,我们将这个函数为回调函数。fs.readFile调用时所做的工作只是将异步式I/O请求发送给操作系统,然后立即返回并执行后面的语句,执行完成以后进入事件循环监听事件。当fs接收到I/O请求完成的事件时,事件循环会主动调用回调函数以完成后续工作。因此我们会先看到end.再看到txt文件内容。
 
Node.js也提供了同步读取文件的API:
   //readfilesync.js
var fs = require('fs');
var data = fs.readFileSync('file.txt','utf-8');
console.log(data);
console.log('end');

结果如下:

 
 
 
    
 
 
原文地址:https://www.cnblogs.com/andgoo/p/2816500.html