了解Node.js的异步式I/O与事件式编程

Node.js最大的特点就是异步式I/O(非阻塞I/O)与事件紧密结合的编程模式。

一、异步式I/O和同步式I/O

1.什么是阻塞式I/O:线程在执行过程中遇到磁盘读写或网络通信(统称为I/O操作),通常要耗费很长的时间,这时系统会剥夺这个线程的CPU控制权,使其暂停执行同时将资源让给其他的工作线程,这种调度方式称为阻塞。当I/O操作完毕时,操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行,这种I/O模式就是同步式I/O或阻塞式I/O。

2.异步式I/O或非阻塞式I/O:(针对所有的I/O操作不采用阻塞的策略)当线程遇到I/O操作时,将I/O请求发送给操作系统,继续执行下一条语句,当操作系统完成I/O操作时,以事件的形式通知执行I/O操作的线程,线程会在特定的时候处理这个事件。为了处理异步I/O,线程必须有事件循环,不断的检查有没有待处理事件,依次予以处理。

3.在非阻塞模式下,一个线程永远在执行计算操作,这个线程所使用的CPU核心利用率永远是100%,I/O以事件的方式通知,并且线程不会被阻塞,永远都在利用CPU。

4.单线程事件驱动的异步式I/O与比传统的多线程阻塞式I/O优点和缺点:异步式I/O就是少了多线程的开销,当然异步式编程缺点是不符合人们程序设计思维,让控制流变得晦涩难懂。


例子:

新建一个file.txt文件,里面随便输入文字即可,和下面js保存在同一目录中。

(1)异步式读取文件

新创建一个AsynchronousRead.js文件

var fs = require('fs');
fs.readFile('file.txt','utf-8',function(err,data){
	if(err){
		console.error(err);
	}else{
		console.error(data);
	}
});
console.log('end.');

在cmd中运行输出结果是:


(2)同步式读取文件

新建一个SynchronousRead.js文件

var fs = require('fs');
var data = fs.readFileSync('file.txt','utf-8');
console.log(data);
console.log('end.');
在cmd中运行输出结果是:


存在的差异是因为:fs.readFIle调用时所作的工作只是将异步式I/O请求发送给了操作系统,然后立即返回并执行后面的语句,执行完成以后进入事件循环监听事件。当fs接收到I/O请求完成事件时,事件循环会主动调用回调函数以完成后续工作,因此会先看到end.再看见file.txt文件内容

二、事件

Node,js所有的异步I/O操作在完成时都会发送一个事件到事件队列。

1.事件由EventEmitter对象提供。用一个例子说明:

创建一个event.js

var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter();
event.on('some_event',function(){
	console.log('some_event occured.');
});
setTimeout(function(){
	event.emit('some_event');
},1000);
原理是:event对象注册了事件some_event的一个监听器,然后通过setTimeout在1000毫秒以后向event对象发送事件some_event,此时会调用some_event的监听器。

2.Node.js的事件循环机制

事件的回调函数在执行过程中,可能会发出I/O请求或直接发射(emit)事件,执行完毕后再返回时间循环,时间循环会检查事件队列中有没有微处理的事件,直到程序结束。

Node.js的事件循环对开发者不可见,由libev库实现。libev时间循环的每一次迭代,在Node.js中就是一次Tick,libev不断检查是否有活动的、可供检测的事件监听器,直到检测不到时才退出事件循环,进程结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值