node.js学习笔记(7) 事件机制

简介:

在web前端的编程中,事件的应用十分广泛,DOM上的各种事件,比如onclick 、onfocus等等。

在ajax大规模应用之后,异步请求更是得到广泛的认同,而ajax亦是基于事件机制的。


Node.js的事件机制是基于V8引擎实现的事件驱动I/O,充分呢利用了异步I/O解决了单线程编程模型的性能瓶颈。


事件机制的实现

Node.js内置了events模块,Events模块(events.EventEmitter)是一个简单的事件监听器模式的实现。具有addListener/on,once,removeListener,removeAllListeners,emit等基本的事件监听模式的方法实现。


第一个events示例,events-1.js:

var events = require('events');

//开一家餐馆
var restaurant = new events.EventEmitter();

/*
 EventEmitter.emit(event, [arg1], [arg2], [...])   触发指定事件
 参数1:event  字符串,事件名
 参数2:可选参数,按顺序传入回调函数的参数
 返回值:该事件是否有监听
 */
//定义点菜事件
restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
});
//定义埋单事件
restaurant.on('pay', function(num) {
    console.log(num + "号桌, 埋单");
});
//1号桌,点菜
restaurant.emit('order', '红烧肉', 1);
//2号桌,点菜
restaurant.emit('order', '炒青菜', 2);
//3号桌,点菜
restaurant.emit('order', '土豆丝', 3);
//1号桌,埋单
restaurant.emit('pay', 1);
//2号桌,埋单
restaurant.emit('pay', 2);
//1号桌,埋单
restaurant.emit('pay', 3);


运行events-1.js:

lee@mypc ~/works/nodejs/study7 $ node events-1.js
1号桌,点菜:红烧肉
2号桌,点菜:炒青菜
3号桌,点菜:土豆丝
1号桌, 埋单
2号桌, 埋单
3号桌, 埋单

这是一个简单的示例,restaurant监听了两个事件"order"和"pay",顾客点菜和埋单时分别触发order和pay。


第二个events示例,假设点菜需要12个步骤,该怎么办?

events-2.js:


var events = require('events');

var restaurant = new events.EventEmitter();

/*
 EventEmitter.emit(event, [arg1], [arg2], [...])   触发指定事件
 参数1:event  字符串,事件名
 参数2:可选参数,按顺序传入回调函数的参数
 返回值:该事件是否有监听
 */
var i=1;
restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.emit('order', '红烧肉', 1);


因为order有12个步骤,所以我们添加了12个order事件。

运行结果:


lee@mypc ~/works/nodejs/study7 $ node events-2.js
(node) warning: possible EventEmitter memory leak detected. 11 order listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
    at EventEmitter.addListener (events.js:239:17)
    at Object.<anonymous> (/home/lee/works/nodejs/study7/events-2.js:66:12)
    at Module._compile (module.js:425:26)
    at Object.Module._extensions..js (module.js:432:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:313:12)
    at Function.Module.runMain (module.js:457:10)
    at startup (node.js:138:18)
    at node.js:974:3
1号桌,点菜:红烧肉
点菜第1步
1号桌,点菜:红烧肉
点菜第2步
1号桌,点菜:红烧肉
点菜第3步
1号桌,点菜:红烧肉
点菜第4步
1号桌,点菜:红烧肉
点菜第5步
1号桌,点菜:红烧肉
点菜第6步
1号桌,点菜:红烧肉
点菜第7步
1号桌,点菜:红烧肉
点菜第8步
1号桌,点菜:红烧肉
点菜第9步
1号桌,点菜:红烧肉
点菜第10步
1号桌,点菜:红烧肉
点菜第11步
1号桌,点菜:红烧肉
点菜第12步
虽然成功完成了12个步骤,但是nodejs在添加第11个order时发出警告。这是因为events默认最大监听数量是10个(同一个事件,不同事件则没有限制)。


改进一下吧,events-3.js:


var events = require('events');

var restaurant = new events.EventEmitter();

restaurant.setMaxListeners(20);
/*
 EventEmitter.emit(event, [arg1], [arg2], [...])   触发指定事件
 参数1:event  字符串,事件名
 参数2:可选参数,按顺序传入回调函数的参数
 返回值:该事件是否有监听
 */
var i=1;
restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});

restaurant.on('order', function(name, num) {
    console.log(num + "号桌,点菜:" + name );
    console.log('点菜第'+(i++)+'步');
});


restaurant.emit('order', '红烧肉', 1);

再看运行结果:


lee@mypc ~/works/nodejs/study7 $ node events-3.js
1号桌,点菜:红烧肉
点菜第1步
1号桌,点菜:红烧肉
点菜第2步
1号桌,点菜:红烧肉
点菜第3步
1号桌,点菜:红烧肉
点菜第4步
1号桌,点菜:红烧肉
点菜第5步
1号桌,点菜:红烧肉
点菜第6步
1号桌,点菜:红烧肉
点菜第7步
1号桌,点菜:红烧肉
点菜第8步
1号桌,点菜:红烧肉
点菜第9步
1号桌,点菜:红烧肉
点菜第10步
1号桌,点菜:红烧肉
点菜第11步
1号桌,点菜:红烧肉
点菜第12步
Perfact !





目录
相关文章
|
5月前
|
存储 JavaScript 前端开发
深入理解JavaScript中的事件循环(Event Loop):机制与实现
【10月更文挑战第12天】深入理解JavaScript中的事件循环(Event Loop):机制与实现
195 3
|
5月前
|
JavaScript
js两种移除事件的方法
js两种移除事件的方法
60 3
|
2月前
|
JavaScript 前端开发 测试技术
盘点原生JavaScript中直接触发事件的方式
本文全面探讨了原生JavaScript中触发事件的多种方式,包括`dispatchEvent`、`Event`构造函数、`CustomEvent`构造器、直接调用事件处理器以及过时的`createEvent`和`initEvent`方法。通过技术案例分析,如模拟点击事件、派发自定义数据加载事件和实现提示框系统,帮助开发者掌握这些方法在实际开发中的应用,提升灵活性与兼容性。
52 3
|
4月前
|
Web App开发 JSON JavaScript
Node.js 中的中间件机制与 Express 应用
Node.js 中的中间件机制与 Express 应用
|
4月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
112 5
|
4月前
|
JavaScript 安全 中间件
深入浅出Node.js中间件机制
【10月更文挑战第36天】在探索Node.js的奥秘之旅中,中间件的概念如同魔法一般,它让复杂的请求处理变得优雅而高效。本文将带你领略这一机制的魅力,从概念到实践,一步步揭示如何利用中间件简化和增强你的应用。
|
4月前
|
消息中间件 JavaScript 中间件
深入浅出Node.js中间件机制
【10月更文挑战第24天】在Node.js的世界里,中间件如同厨房中的调料,为后端服务增添风味。本文将带你走进Node.js的中间件机制,从基础概念到实际应用,一探究竟。通过生动的比喻和直观的代码示例,我们将一起解锁中间件的奥秘,让你轻松成为后端料理高手。
68 1
|
5月前
|
存储 JavaScript 前端开发
js事件队列
【10月更文挑战第15天】
90 6
|
5月前
|
移动开发 JavaScript 前端开发
【JavaScript】JS执行机制--同步与异步
【JavaScript】JS执行机制--同步与异步
47 1
|
5月前
|
JSON JavaScript 中间件
深入浅出Node.js中间件机制
本文将带你探索Node.js中一个核心概念——中间件机制。我们将通过浅显的语言和生动的比喻,揭示中间件如何作为请求和响应之间的“交通枢纽”,在应用程序中起到至关重要的作用。从基础原理到实际应用,你将了解到中间件不仅简化了代码结构,还提高了开发效率,是Node.js开发不可或缺的一部分。
75 1

热门文章

最新文章