开发者社区> 黎燃> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

简介: 实战Node.js原理对于阻塞和EventEmitter及其继承的运用心得
+关注继续查看

@[toc]

基本概念

在这里插入图片描述

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

$ node

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

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

使用node JS,我们不仅实现了一个应用程序,还实现了整个HTTP服务器。

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

回调函数

Node.jsS异步编程的直接体现是回调。

阻塞代码

异步编程依赖于回调,但不能说在使用回调后程序将是异步的。
完成任务后将调用回调函数。节点使用大量回调函数。
节点的所有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文件。执行结果如下:

程序执行完毕
Error: ENOENT, open 'input.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); 
}); 
on(event, listener)

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

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

继承 EventEmitter

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

1.首先,具有实体函数的对象实现了符合语义的事件。事件的侦听和发生应该是对象的一种方法。

2.其次,JavaScript的对象机制是基于原型的,支持部分多重继承。继承EventEmitter不会干扰对象的原始继承关系。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
JavaWeb对于JSP基础语法实战详解
JavaWeb对于JSP基础语法实战详解
39 0
【Vue.js 入门与实战】--结合Node手写JSONP服务器剖析JSONP原理
由于浏览器的安全性限制,不允许AJAX访问协议不同、域名不同、端口号不同的 数据接口,浏览器认为这种访问不安全。因为后端服务器的接口比如运行在33 或44上,但是前端网站运行在80端口。前后端端口不一样,要实现跨域访问,前后端合作开发更多的使用JSONP。
28 0
No converter found for return value of type: class java.util.ArrayList错误问题
No converter found for return value of type: class java.util.ArrayList错误问题
43 0
UI5 framework异步加载javascript的solution - 动态创建script node
Created by Jerry Wang, last modified on Sep 22, 2015
45 0
内网穿透工具的原理与开发实战
内网穿透工具的原理与开发实战有时候,我们在外想要访问家里主机的资料,要么由于主机处于家庭路由器下,是非公网IP,要么就是是运营商随机分配的一个公网IP,都很难直接连上主机获取资料。那么,有什么办法可以解决这一难题?答案就是 内网穿透。
9293 0
Node.js EventEmitter
Node.js EventEmitter Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。 Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.readStream 对象会在文件被打开的时候触发一个事件。
961 0
Java HashMap类源码解析(续)-TreeNode
  由于TreeNode本身是红黑树的实现,所以在分析TreeNode的之前我还是摸了一篇算法导论里红黑树的读书笔记:算法导论——红黑树,从伪代码行数也可以看出完整的红黑树的插入和删除操作代码是很长的,下面源码分析部分的行数就更多了,所以所谓手写红黑树画个图分析下逻辑还行,手写代码估计要写死(滑稽)   TreeNode从JDK8开始引入,作用是当HashMap解决冲突的链表长度超过了8时,生成一个红黑树来加速查找和插入,这里树结构存在并不影响本身依然存在线性链表结构,意思是Node.next这个属性依然有效,所以说树替换了线性链表依然还是链表法解决冲突,只不过链表的实现策略换了。
18936 0
Java TreeMap工作原理及实现
http://yikun.github.io/2015/04/06/Java-TreeMap%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E5%8F%8A%E5%AE%9E%E7%8E%B0/ ...
845 0
+关注
112
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载