内容简介:Node.js的events 模块功能强大,除了常规的监听、触发,还支持事件顺序(prependListener),本文只是写着玩玩,真正要用的话,还是选择成熟稳定的东西较好!内容概览: 以下订阅=监听、发布=触发;一般来说,四个功能:
Node.js的events 模块功能强大,除了常规的监听、触发,还支持事件顺序(prependListener),本文只是写着玩玩,真正要用的话,还是选择成熟稳定的东西较好!
内容概览: 以下订阅=监听、发布=触发;一般来说, 先订阅事件 , 再发布事件 ;就像打电话一样,电话没拨通(订阅),你就开始说话要干嘛干嘛(发布),这时候订阅是无效的!!!因为触发在前、监听在后,触发的时候没有监听,监听的时候已经结束, 二者不在一个频道!!! 沟通就是无效的。。。
四个功能:
- 订阅on
- 订阅once(一次性
- 发布emit
- 注销off
- 错误监听error
构造函数
// 发布订阅,回调函数版本 function EvtEmit() { // 事件参数队列 this.evtList = []; } 复制代码
原型
EvtEmit.prototype = { constructor: EvtEmit, // 订阅事件(监听) on(emitName, handler) { // console.debug(`EvtEmit -- on: ${emitName}`); if (!emitName) return; if (!this.evtList.some(evt => evt.emitName === emitName)) { this.evtList.push({ emitName, // 事件名称 handler, once: emitName === 'error' ? true : false }); } }, // 订阅事件(一次性 once(emitName, handler) { if (!emitName) return; if (!this.evtList.some(evt => evt.emitName === emitName)) { this.evtList.push({ emitName, // 事件名称 handler, once: true }); } }, // 发布事件(触发) emit(emitName, ...param) { // console.debug(`EvtEmit -- emit: ${emitName}`); if (!emitName) return; let evtThis = this.evtList.find(evt => evt.emitName === emitName); if (!evtThis) { if (emitName !== 'error') { console.warn(`请先使用监听on('${emitName}', callback),再emit('${emitName}')!`); } return; } // 一次性订阅 if (evtThis.once) this.off(emitName); // 监听[emitName]回调的错误 try { evtThis.handler(...param); } catch (err) { // 不使用 on('error', callback)监听时,打印错误 if (!this.evtList.some(evt => evt.emitName === 'error')) { console.error(`on('${emitName}', callback) -> callback Error: ${err}`); } // 错误触发,可以使用 on('error', callback)监听 this.emit('error', { emitName, err }); } }, // 注销事件订阅 off(emitName, callback = null) { let arr = this.evtList.filter(evt => evt.emitName !== emitName); this.evtList = arr; arr = null; if (callback) { callback.call(this, emitName); } } }; 复制代码
使用
同正常的发布订阅一样,先订阅(on)再发布(emit);
const evt = new EvtEmit(); // 监听'run'事件 // 执行1次on监听,10次回调函数 evt.on('run', res => { console.log('res: ', res); // 注销监听,以下 emit 之后将不再触发 on;注释之后将无限调用 if (--res < 1) { evt.off('run', emitName => { console.log(`on('${emitName}')已注销!`); }); return; } evt.emit('run', res); }); evt.emit('run', 10); // 监听'go'事件 // 一秒执行回调 evt.on('go', res => { console.log('res: ', res); }); // 1秒后订阅'go'事件 setTimeout(() => { evt.emit('go', 'go'); }, 1000); 复制代码
输出
错误监听
try/catch
执行监听的回调函数,捕获错误然后触发 emit('error', err)
,通过 on('error', callback)
监听错误;
为什么需要 try/catch?
不使用try/catch捕获错误的话,一旦发生错误,进程就挂了,这时,后续不需要依赖你这次操作结果的 程序就会跑不下去了!!!(如下 打印 'after go',如果没有try/catch,那么他就不会被打印);
这在服务端用的比较多,想象一下,一个接口因为某次调用的参数不合法或者其他因素,导致程序中断而影响到后续使用,可能产生‘事故’!
try/catch 包裹回调函数的执行
// 发布事件(触发) emit(emitName, ...param) { // console.debug(`EvtEmit -- emit: ${emitName}`); if (!emitName) return; let evtThis = this.evtList.find(evt => evt.emitName === emitName); if (!evtThis) { if (emitName !== 'error') { console.warn(`请先使用监听on('${emitName}', callback),再emit('${emitName}')!`); } return; } // 一次性订阅 if (evtThis.once) this.off(emitName); // 监听[emitName]回调的错误 try { evtThis.handler(...param); } catch (err) { // 不使用 on('error', callback)监听时,打印错误 if (!this.evtList.some(evt => evt.emitName === 'error')) { console.error(`on('${emitName}', callback) -> callback Error: ${err}`); } // 错误触发,可以使用 on('error', callback)监听 this.emit('error', { emitName, err }); } }, 复制代码
错误捕获:
evt.on('error', ({ emitName, err }) => { console.error(`on('${emitName}', callback) -> callback Error: ${err}`); }) evt.on('go', res => { err; // 错误会被 try/catch 捕获 console.log('res: ', res); }); evt.emit('go', 'go'); console.log('after go'); // 没有 try/catch 的话,不会执行 复制代码
全部代码 EvtEmit_callback.js:
// EvtEmit_callback.js // 发布订阅,回调函数版本 function EvtEmit() { // 事件参数队列 this.evtList = []; } EvtEmit.prototype = { constructor: EvtEmit, // 订阅事件(监听) on(emitName, handler) { // console.debug(`EvtEmit -- on: ${emitName}`); if (!emitName) return; if (!this.evtList.some(evt => evt.emitName === emitName)) { this.evtList.push({ emitName, // 事件名称 handler, once: emitName === 'error' ? true : false }); } }, // 订阅事件(一次性 once(emitName, handler) { if (!emitName) return; if (!this.evtList.some(evt => evt.emitName === emitName)) { this.evtList.push({ emitName, // 事件名称 handler, once: true }); } }, // 发布事件(触发) emit(emitName, ...param) { // console.debug(`EvtEmit -- emit: ${emitName}`); if (!emitName) return; let evtThis = this.evtList.find(evt => evt.emitName === emitName); if (!evtThis) { if (emitName !== 'error') { console.warn(`请先使用监听on('${emitName}', callback),再emit('${emitName}')!`); } return; } // 一次性订阅 if (evtThis.once) this.off(emitName); // 监听[emitName]回调的错误 try { evtThis.handler(...param); } catch (err) { // 不使用 on('error', callback)监听时,打印错误 if (!this.evtList.some(evt => evt.emitName === 'error')) { console.error(`on('${emitName}', callback) -> callback Error: ${err}`); } // 错误触发,可以使用 on('error', callback)监听 this.emit('error', { emitName, err }); } }, // 注销事件订阅 off(emitName, callback = null) { let arr = this.evtList.filter(evt => evt.emitName !== emitName); this.evtList = arr; arr = null; if (callback) { callback.call(this, emitName); } } }; const evt = new EvtEmit(); // 执行1次on监听,10次回调函数 evt.on('run', res => { console.log('res: ', res); // 注销监听,以下 emit 之后将不再触发 on;注释之后将无限调用 if (--res < 1) { evt.off('run', emitName => { console.log(`on('${emitName}')已注销!`); }); return; } evt.emit('run', res); }); evt.emit('run', 10); // evt.on('error', ({ emitName, err }) => { // console.error(`on('${emitName}', callback) -> callback Error: ${err}`); // }) // evt.on('go', res => { // err; // 错误会被 try/catch 捕获 // console.log('res: ', res); // }); // evt.emit('go', 'go'); // console.log('after go'); // 没有 try/catch 的话,不会执行 复制代码
参考
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 玩玩awk
- 玩玩区块链:概念
- 玩玩智能家居2:ESPEasy
- [NodeJS][Golang] 玩玩看 Line Beacon
- 天天 CRUD 的我,也想玩玩高大上的 Prometheus
- IPv6闲谈-一起玩玩IPv6自动配置
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数据结构 Python语言描述
[美] Kenneth A. Lambert 兰伯特 / 李军 / 人民邮电出版社 / 2017-12-1 / CNY 69.00
在计算机科学中,数据结构是一门进阶性课程,概念抽象,难度较大。Python语言的语法简单,交互性强。用Python来讲解数据结构等主题,比C语言等实现起来更为容易,更为清晰。 《数据结构 Python语言描述》第1章简单介绍了Python语言的基础知识和特性。第2章到第4章对抽象数据类型、数据结构、复杂度分析、数组和线性链表结构进行了详细介绍,第5章和第6章重点介绍了面向对象设计的相关知识、......一起来看看 《数据结构 Python语言描述》 这本书的介绍吧!