博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
node不懂Events模块没法玩了
阅读量:4087 次
发布时间:2019-05-25

本文共 4248 字,大约阅读时间需要 14 分钟。

Events的重要性:

node是单线程,基于事件驱动的,所以node中很多模块都是基于events去实现的,所以event模块在node中属于很重要的模块。

Events常用的API:

  1. emitter.on(eventName, listener)和emitter.addListener(eventName, listener)用来添加订阅事件
  2. emitter.once(eventName, listener)用来添加只执行一次的事件
  3. emitter.prependListener(eventName, listener)用来在事件队列前面添加事件
  4. emitter.emit(eventName[, ...args])用来触发事件队列执行
  5. emitter.removeListener(eventName, listener)用来移除某个事件队列
  6. EventEmitter.defaultMaxListeners 默认事件队列的长度
  7. emitter.setMaxListeners 设置最大队列的长度
  8. emitter.prototype.getMaxListeners 获取最大队列的长度

Event的核心原理:

events模块是基于发布订阅模式来实现的,其核心的逻辑可以用下面的代码表示:

function Event(){    this.events=[];}//添加订阅者Events.prototype.on = function(listener){    if(typeof listener === 'function'){        this.events.push(listener)    }}//执行订阅回调Events.prototype.emit = function(){    this.events.forEach(event=>evetn());}复制代码

Events.prototype.on 实现

function EventEmitter(){    this._events={};//用来存储各种不同类型的事件队列    this._maxListeners = undefined; // 默认实例上没有最大监听数}EventEmitter.defaultMaxListeners//默认事件队列的长度为10EventEmitter.prototype.setMaxListeners = function(count){    this._maxListeners = count;}EventEmitter.prototype.getMaxListeners = function(){    if(!this._maxListeners){ // 如果没设置过那就是10个        return EventEmitter.defaultMaxListeners;    }    return this._maxListeners}EventEmitter.prototype.on = EventEmitter.prototype.addListener=function(eventName,listener){    if(!this._events){this._events = Object.create(null);}//防止缓存不存在,创建一个没有原型的干净缓存    if(eventName!=='newListener'){//newListener每次绑定事件都会调用这个里面的回调并且传入当前事件名        if(this._events['newListener']){            this._events['newListener'].forEach(fn=>fn(eventsName))        }    }    if(this.events[eventName]){//已存在队列就直接将回调放入         if(this._events[eventName].length === this.getMaxListeners()){            console.warn(`Possible EventEmitter memory leak detected.${this._events[eventName].length}${String(eventName)}listeners added. Use emitter.setMaxListeners() toincrease limit'`)        }        this._events[eventName].push(callback);    }else{//不存在就创建一个队列再放入        if(this._events[eventName].length === this.getMaxListeners()){            console.warn(`Possible EventEmitter memory leak detected.${this._events[eventName].length}${String(eventName)}listeners added. Use emitter.setMaxListeners() toincrease limit'`)        }        this._events[eventsName]=[listener];    }}module.exports = EventEmitter;复制代码

Events.prototype.prependListener 实现

EventEmitter.prototype.prependListener = function (eventName,listener) {  this.on(eventName,listener, true);}//修改EventEmitter.prototype.on让其可以选择添加事件的位置EventEmitter.prototype.on = EventEmitter.prototype.addListener=function(eventName,listener,flag){    if(!this._events){this._events = Object.create(null);}    if(eventName!=='newListener'){        if(this._events['newListener']){            this._events['newListener'].forEach(fn=>fn(eventsName))        }    }    if(this.events[eventName]){        if(!flag){//根据flag来判断添加的位置            this._events[eventName].push(callback);        }else{            this._events[eventName].unshift(callback);           }    }else{        this._events[eventsName]=[listener];    }}复制代码

Events.prototype.once 实现

EventEmitter.prototype.once = function(eventName,listener){    function once(){//once缓存listener,不然的话移除时找不到listener        listener();        this.removeListener(eventName,once)    }    this.on(eventName,once)}复制代码

Events.prototype.emit 实现

EventEmitter.prototype.emit = function(eventName,...args){    if(this._events[eventName]){        this._events.forEach(fn=>{//使用箭头函数,所以this指向外层的this即emit实例            fn.call(this,...args)        })    }}复制代码

Events.prototype.removeListener 实现

Events.prototype.removeListener = finction(eventName,listener){//需要从相应的事件队列中筛选排除传入的listener    this._events[eventName].filter(fn=>{        return listener!==item &&item.g!===listener//第二个针对于用once绑定的事件回调    })}EventEmitter.prototype.once = function(eventName,listener){    function once(){//once缓存listener,不然的话移除时找不到listener        listener();        this.removeListener(eventName,once)    }    once.g = listener;//用来缓存原来的listener,删除时用到    this.on(eventName,once)}复制代码

结语:

以上就是关于Events模块原理的介绍,如果有错误欢迎指正,本文参考:

  1. javascript设计模式

作者:梦想攻城狮
链接:https://juejin.im/post/5b990be75188255c7566b479
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的文章
OS + Unix Aix telnet
查看>>
IBM Lotus
查看>>
Linux +Win LAMPP Tools XAMPP 1.7.3 / 5.6.3
查看>>
my read_university
查看>>
network manager
查看>>
OS + Linux Disk disk lvm / disk partition / disk mount / disk io
查看>>
net TCP/IP / TIME_WAIT / tcpip / iperf / cain
查看>>
webServer kzserver/1.0.0
查看>>
OS + Unix IBM Aix basic / topas / nmon / filemon / vmstat / iostat / sysstat/sar
查看>>
OS + Linux DNS Server Bind
查看>>
linux下安装django
查看>>
Android 解决TextView设置文本和富文本SpannableString自动换行留空白问题
查看>>
Android开发中Button按钮绑定监听器的方式完全解析
查看>>
Android自定义View实现商品评价星星评分控件
查看>>
postgresql监控工具pgstatspack的安装及使用
查看>>
postgresql查看表的和索引的情况,判断是否膨胀
查看>>
postgresql中根据oid和filenode去找表的物理文件的位置
查看>>
postgresql减少wal日志生成量的方法
查看>>
swift中单例的创建及销毁
查看>>
获取App Store中App的ipa包
查看>>