nodeJS
来源:互联网 发布:gentlewoman 知乎 编辑:程序博客网 时间:2024/05/16 16:04
Events 事件模块
说明
大多数 Node.js 核心 API 都采用异步事件驱动架构,其中某些类型的对象(触发器)会周期性的触发命名事件来调用函数对象(监听器),所有能触发事件的对象都是
EventEmitter
类的实例,允许将一个或者多个函数绑定到会被对象触发的命名事件上
EventEmitter
会按照监听器函数的注册顺序同步的调用所有监听器,所以需要确保事件的正确排序且避免竞争条件或逻辑错误,监听器函数中可以使用setImmediate()
或者process.nextTick()
方法切换到异步操作模式
参考
- Node.js 文档
- JavaScript 标准参考教程 Node.js
// 获取事件发生器的构造函数 const Emitter = require('events').EventEmitter; // 创建事件发生器实例,也就是消息中心,用来注册和触发事件(订阅和发布) const emitter = new Emitter(); // 事件响应函数 function handle1(some) { console.log('handle - ', some); } function handle2(some) { console.log('同步的', some); process.nextTick(function () { console.log('nextTick', some); }) setImmediate(() => { console.log('setImmediate', some); }) } // on 注册事件,指定回调函数 emitter.on('test', handle1); emitter.on('test', handle2) // emit 触发事件 setTimeout(function () { console.log('start emit'); emitter.emit('test', 'test data'); console.log('end emit'); }, 1000); /* start emit handle - test data 同步的 test data end emit nextTick test data setImmediate test data */
Event Emitter 接口可以部署在任意对象上,使得这些对象也能够订阅和发布消息
// 获取事件发生器的构造函数 const Emitter = require('events').EventEmitter; // 创建构造函数 function Test() { this.name = 'test'; } /* 使构造函数的原型继承事件发生器的原型方法 Object.create(a) 以 a 为原型创建对象 将事件发生器添加到构造函数原型对象的原型上,可以方便构造函数原型上继续添加方法(注意不要将原型对象覆盖) */ // Test.prototype.__proto__ = Emitter.prototype; Test.prototype = Object.create(Emitter.prototype); Test.prototype.say = function () { console.log(this.name); } // 创建实例 const test = new Test(); // 事件响应函数 function handle(some) { console.log('handle - ', some); } // 注册事件 test.on('test', handle); // 触发事件 setTimeout(function () { console.log('start emit'); test.emit('test', 'test extend'); console.log('end emit'); }, 1000);
Node.js 内置工具 util 模块提供 inherits 方法,用于继承
const Emitter = require('events').EventEmitter; const util = require('util'); function Test() { this.name = 'test name'; this.on('newListener', function (listener) { console.log('listener: ', listener); }) } Test.prototype.init = function () { this.emit('open', 'init open'); setTimeout(() => { this.emit('close', 'init close'); }, 1000) } util.inherits(Test, Emitter); // Emitter 的接口继承到 Test 上 const test = new Test(); function handle(text) { console.log(text); } test.on('open', handle); test.on('close', handle); test.init();
Event Emitter 实例方法
on()
给事件添加监听器函数,添加多个事件监听器会按照添加顺序依次执行once()
给事件添加监听器函数,只执行一次addListener()
与 on 一样emit()
按照监听器的注册顺序同步地调用每个注册在此事件下的监听器,并提供参数listeners()
返回名某个事件下的监听器数组removeListener()
两个参数:eventName, listener ,移除某个事件下的指定监听器removeAllListeners()
移除某个事件下的所有监听函数setMaxListeners()
修改指定实例的事件监听器上限getMaxListeners()
返回监听器限制值prependListener()
添加事件监听器到指定事件的开头prependOnceListener()
添加事件监听器到指定事件的开头,只执行一次listenerCount()
返回某个事件的监听器数量eventNames()
返回已注册的事件名的数组
const Emitter = require('events').EventEmitter; const emitter = new Emitter(); function handle (f) { return function (text) { console.log(f, text); } } // once 指定事件的监听函数只执行一次 emitter.once('onceEvent', handle('once')); // on 指定事件的监听函数 emitter.on('onceEvent', handle('on')); // addListener 与 on 一样 emitter.addListener('onceEvent', handle('addListener')); // listeners 返回同一个事件下回调函数的数组 const listeners = emitter.listeners('onceEvent'); console.log(listeners); // length 3 // emit 触发事件 emitter.emit('onceEvent', 'emit1'); /* once emit1 on emit1 addListener emit1 */ emitter.emit('onceEvent', 'emit2'); /* // once 只执行一次,所以没有响应 on emit2 addListener emit2 */ // removeAllListeners 移除某个事件的所有监听函数 emitter.removeAllListeners('onceEvent'); emitter.emit('onceEvent', 'emit3'); // 没响应 function handle2(text) { console.log('handle2 ', text); } function handle3(text) { console.log('handle3 ', text); } function handle4(text) { console.log('handle4 ', text); } function handle5(text) { console.log('handle5 ', text); } emitter.on('twiceEvent', handle2); emitter.on('twiceEvent', handle3); // prependListener 添加事件监听器到指定事件的开头 emitter.prependListener('twiceEvent', handle4); // 先执行 // prependOnceListener 添加事件监听器到指定事件的开头,只执行一次 emitter.prependOnceListener('twiceEvent', handle5); // removeListener 移除某个事件的某个监听函数 emitter.removeListener('twiceEvent', handle2); emitter.emit('twiceEvent', 'emit4'); // handle3 emit4; handle2 不响应 // setMaxListeners 修改指定实例的事件监听器上限 emitter.setMaxListeners(20); // 返回监听器限制值 emitter.getMaxListeners(); // 20 // listenerCount 返回某个事件的监听器数量 emitter.listenerCount('twiceEvent') // 2 // eventNames 返回已注册的事件名的数组 emitter.eventNames() // [ 'twiceEvent' ]
阅读全文
0 0
- nodejs
- NodeJs
- nodejs
- nodejs
- nodejs
- nodejs
- nodejs
- nodejs
- nodejs
- nodejs
- NodeJs
- nodejs
- NodeJS
- nodejs
- nodejs
- nodejs
- NodeJS
- nodejs
- 接口继承示例:模拟银行存取款
- ZooKeeper原理
- 2017_11_23 学习echarts之饼状、柱状、gl(三维柱状)、map地图
- 小java菜鸟的些许感受。
- 机器学习笔记(一)
- nodeJS
- 485. Max Consecutive Ones
- Android APK安全: 代码混淆且加壳防止反编译
- pdf.js预览pdf文件
- javascript 实现购物车
- juuery获取元素的所有宽高(包括内边距和外边距)
- Java多线程常用面试题(含答案,精心总结整理)
- Laravel Call to a member function setCookie() on null
- 关于正则化的理解