nodejs中的事件机制以及事件协作和雪崩问题的改进方法
2016-06-17 11:37
579 查看
本文为阅读《深入浅出node.js》后总结部分内容而得。文中代码皆来源于该书
比如以下代码:
注意:在nodejs中,当我们对一个事件添加了超过10个侦听器,nodejs会发出警告,因为设计者认为侦听器太多会导致内存泄漏。
使用eventProxy模块实现上述功能的代码如下:
简单事件机制
通过事件机制,我们不用关心组件内部是怎样的,只需要关注在我们所需的事件点即可。比如以下代码:
var options = { host: 'wwww.google.com', port: 80, path: '/upload', method: 'POST' }; var req = http.request(option, function(res) { console.log('STATU:' + res.statusCode); console.log('HEADERS:' + JSON.stringify(res.header)); res.setEncoding('utf8'); res.on('data', function(chunk) { console.log('BODY:' + chunk); }); }); req.on('error', function(e) { console.log('problem with request:' + e.message); }); req.write('data\n'); req.write('data\n'); requestAnimationFrame.end()在实现以上代码的过程中,我们不需要了解req的内部流程,只需要知道error,data这些业务事件点。
注意:在nodejs中,当我们对一个事件添加了超过10个侦听器,nodejs会发出警告,因为设计者认为侦听器太多会导致内存泄漏。
多事件协作
加入我们一个操作需要对多个事件进行操作,比如在渲染页面时,我们通过同时向多个数据源发送请求,为了实现‘当是三个事件都完成后,才执行下一操作’,程序可能会写成这样api.getUser('username', function(profile) { api.getTimeline('username', function(timeline) { api.getSkin('username', function(skin) { //todo }); }); });可是这种层层嵌套的形式,就会导致上一个请求完成后才进行下一个请求,无法最大化利用底层api服务器。为了解决这种多事件协作,我们可以使用github上的EventProxy模块(地址:https://github.com/JacksonTian/eventproxy)
使用eventProxy模块实现上述功能的代码如下:
var proxy = new EventProxy(); proxy.all('profile', 'timeline', 'skin', function(profile, timeline, skin) {//all方法的作用是保证执行完三个方法后,执行回调函数并传入方法接收到的数据 //todo }); api.getUser('username', function(profile) { proxy.emit('timeline', timeline); }); api.getSkin('username', function(skin) { proxy.emit('skin', skin); });
利用事件队列解决雪崩问题
雪崩问题就是在浏览器缓存失效后,并发访问量大量涌入数据库执行查询操作,导致数据库无法同时承受如此大的访问量,从而影响网站效果。在nodejs中一句数据库查询的代码为:var select = function(callback) { db.select('SQL', function(results) { callback(results);//比如传入的函数是展示数据,那么该句的作用就是将查询后返回的数据展示出来 }); };那么在该代码上,做一些改进,添加一个状态锁,以防止大规模并发,改进代码为:
var status = 'ready'; var select = function (callback) { if (status === 'ready') { status = 'pending'; db.select('SQL', function (results) { callback(results);//比如传入的函数是展示数据,那么该句的作用就是将查询后返回的数据展示出来 status = 'ready'; }); } };但是改代码虽然避免了并发查询数据库操作,却导致并发的几个操作只有第一个操作被执行,后面几个不了了之,故该方法仍需改进,为更好的解决并发问题,我们仍然可以使用eventProxy模块,将所有并发操作放入一个等待队列,代码如下:
var proxy = new EventProxy(); var status = 'ready'; var select = function (callback) { proxy.once('selected', callback);//将该实例的该操作放入队列,并且操作只执行一次 if (status === 'ready') { status = 'pending'; db.select('SQL', function (results) { proxy.emit('selected',results);//将该操作返回的数据作为回调函数的输入参数,执行回调函数 status = 'ready'; }); } };
相关文章推荐
- nvm 解决nodejs无法全局/usr/bin/node问题
- Node.js-视图引擎【1】-Swig集成express的安装与配置
- node.js 使用事件机制
- node.js学习笔记(8)--multer模块文件上传
- 【leetcode】19. Remove Nth Node From End of List
- 2个项目的免费node.js 服务器
- inode索引节点和硬连接软连接(草稿)
- Nodejs 处理表单提交数据
- node.js Waterline
- ubuntu系统安装nvm node npm cordova
- Node.js 应用程序的 5 条性能建议
- Hadoop可以连上8088,连不上50070,并且jps命令后并没有出现Namenode
- Linode vps使用日志
- Count Complete Tree Nodes
- node 实现SSO
- node起步(安装,建立服务,事件式编程)-01
- 19. Remove Nth Node From End of List [easy] (Python)
- Hadoop-2.4.1源码分析--HDFS HeartBeat(心跳检测)之NameNode端处理数据块增量汇报
- Hadoop-2.4.1源码分析--HDFS HeartBeat(心跳检测)之DataNode端数据块增量汇报
- hadoop Data上jps不出现Datanode