node自学之Nodejs的非阻塞I/O、异步、事件驱动
终极目标:掌握和使用node
本博客目的:记录node学习的进度和心得
内容:Nodejs中的Nodejs的非阻塞I/O、异步、事件驱动。
Nodejs的单线程、非阻塞I/O、事件驱动
在Java、PHP或者.net等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约2MB内存。也就是说,理论上,一个8GB内存的服务器可以同时连接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就需要增加服务器的数量,而Web应用程序的硬件成本当然就上升了。 (高并发场景)
Node.js不为每个客户连接创建一个新的线程,而仅仅使用一个线程。当有用户连接了,就触发一个内部事件,通过非阻塞I/O、事件驱动机制,让Node.js程序宏观上也是并行的。使用Node.js,一个8GB内存的服务器,可以同时处理超过4万用户的连接。
之前,我们使用fs模块的readFile方法是一个异步方法,或者说是非阻塞式IO。
所以代码:
结果:
但是,当我们在外部使用这个异步方法的时候,会出undefined
因为,这个方法是异步的,最后才会返回第3步,data没有在getMime方法结束前返回。
所以,通常的方法是回调函数的方法解决这种异步问题。
Nodejs回调处理异步
相当于callback在异步方法中留了一个钩子,等待异步处理完成,传入data给callback,自然也获取了到这个data。
此外,我们可以使用events模块。
Nodejs events模块处理异步
Node.js 事件循环: Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。
Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发。
Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件(广播与接收广播,即事件驱动)。
首先,查看一下events模块
有很多属性。
通常,我们通过实例化 EventEmitter 类来绑定和监听事件,即广播事件,接收广播,出发事件的相关操作方法。
例如:
注意的是,EventEmitter.emit('to_parent','发送的数据')
中发射to_parent事件并且是把 发送的数据 作为数据传送出去的,这是可以被监听到的。(这类似于vue中的子组件与父组件通信(子传父的情况)。)
类似地,事件的广播和监听可以循环嵌套(事件驱动):
1 | // 引入 events 模块 |
nodejs事件驱动获取数据
所以我们用事件驱动的方法,接收fs异步处理的数据。
拿到了对应的数据
处理fs异步读取的问题
在上一个blog中,fs的readFile是一个异步读取的方法,我们不能正确读取文件,所以采用了fs.readFileSync同步读取。
这里,我们可以使用刚刚讲的两种处理异步的方式解决这个问题。
1、使用回调函数的方式
2、使用event模块的发射事件与监听事件
注意:对应调用的格式和参数要相应修改。