实战Node.js原理对于阻塞和EventEmitter及其继承的运用心得

Posted 黎燃黎燃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实战Node.js原理对于阻塞和EventEmitter及其继承的运用心得相关的知识,希望对你有一定的参考价值。

@[toc]

基本概念

简单地说,Node.js是在服务器端运行的javascript
节点。

$ node

> console.log(Hello 黎燃!);
Hello 黎燃!

然而,对于node JS,概念完全不同。

事实上,我们的web应用程序和相应的web服务器基本相同。
让我们了解一下node JS应用程序由以下部分组成:
1.介绍所需模块:我们可以使用require命令加载node JS模块。
2.创建服务器:服务器可以监听客户端的请求,类似于Apache和nginx等HTTP服务器。
3.接收请求并响应请求的服务器很容易创建。客户端可以使用浏览器或终端发送HTTP请求,服务器收到请求后返回响应数据。

回调函数

阻塞代码

异步编程依赖于回调,但不能说在使用回调后程序将是异步的。
完成任务后将调用回调函数。节点使用大量回调函数。
节点的所有API都支持回调函数。

读取文件后,我们返回文件内容作为回调函数的参数。
这样,在执行代码时就不会阻塞或等待文件I/O操作。
回调函数通常显示为函数的最后一个参数:

function foo1(name, age, callback)  
function foo2(value, callback1, callback2)  

创建主JS文件,代码如下:

var fs = require("fs");

var data = fs.readFileSync(input.txt);

console.log(data.toString());
console.log("程序执行结束!");

非阻塞代码

创建主JS文件,代码如下:

var fs = require("fs");

fs.readFile(input.txt, function (err, data) 
    if (err) return console.error(err);
    console.log(data.toString());
);

console.log("程序执行结束!");

在以上两个例子中,我们理解阻塞调用和非阻塞调用之间的区别。第一个实例在读取文件后执行程序。
在第二个示例中,我们不需要等待文件被读取,因此我们可以在读取文件的同时执行以下代码,这大大提高了程序的性能。

Node.js 事件循环


Node.js使用事件驱动模型。
当web服务器接收到一个请求时,它会关闭并处理该请求,然后为下一个web请求提供服务。
当请求完成时,它将被放回处理队列。当它到达队列的开头时,结果将返回给用户。
引入 events 模块

var events = require(events);

创建 eventEmitter 对象

var eventEmitter = new events.EventEmitter();

绑定事件及事件的处理程序

eventEmitter.on(eventName, eventHandler);

触发事件

eventEmitter.emit(eventName);

Node 应用程序工作原理

创建主JS文件,代码如下:

var fs = require("fs");

fs.readFile(input.txt, function (err, data) 
   if (err)
      console.log(err.stack);
      return;
   
   console.log(data.toString());
);
console.log("程序执行完毕");

在上述程序中,FS Readfile()是一个用于读取文件的异步函数。如果在读取文件期间发生错误,error err对象将输出错误消息。

如果没有发生错误,readfile将跳过err对象的输出,并通过回调函数输出文件内容。

接下来,我们删除输入Txt文件。执行结果如下:

EventEmitter 类

每次有新连接时,服务器对象的net将触发事件,而readstream对象的FS将在文件打开时触发事件。所有生成事件的对象都是EventEmitter实例中的事件。

引入 events 模块

var events = require(events);

创建 eventEmitter 对象

var eventEmitter = new events.EventEmitter();

如果在实例化EventEmitter对象期间发生错误,将触发错误事件。添加新侦听器时,将触发newlistener事件。删除侦听器时,将触发RemovelListener事件。

var EventEmitter = require(events).EventEmitter; 
var event = new EventEmitter(); 
event.on(some_event, function()  
    console.log(some_event 事件触发); 
); 
setTimeout(function()  
    event.emit(some_event); 
, 1000); 

运行此代码,控制台在1秒_事件触发器后输出some。
触发事件时,将依次调用注册到此事件的事件侦听器,并将事件参数作为回调函数参数传递。

var events = require(events); 
var emitter = new events.EventEmitter(); 
emitter.on(someEvent, function(arg1, arg2)  
    console.log(listener1, arg1, arg2); 
); 

注册指定事件的侦听器,并接受字符串事件和回调函数。

server.on(connection, function (stream) 
  console.log(someone connected!);
);

继承 EventEmitter

大多数时候,我们不直接使用EventEmitter,而是在对象中继承它。
所有支持事件响应的核心模块,包括FS、net和HTTP,都是EventEmitter的子类。

以上是关于实战Node.js原理对于阻塞和EventEmitter及其继承的运用心得的主要内容,如果未能解决你的问题,请参考以下文章

《node.js实战》第一章读后感

node.js哲学与核心原理

Node.js实战对于Buffer和Stream模块系统的深入剖析

单线程非阻塞 IO 模型如何在 Node.js 中工作

node.js基本工作原理及流程

实战系列之 Node.js 玩转 Java