发布订阅是主动的,来个例子,我有一个女友,要包,要车。等我有钱了,买包买车。这个过程当中,我要先订阅买包买车,等有钱了在发布。vue
观察者被动执行。我先观察你,你有变化了,我在变化,有点儿相似vue watch数组
例子1bash
先把想干的事情存起来,当真的发生时候,依次将数组中的内容执行。对应关系以下:函数
{
有钱: [买包,买车]
女生失恋: [哭,喝酒]
}
复制代码
代码实现:ui
let EventEmitter = require('events');
let util = require('util');
// 定义一个类
function Girl() {
}
// 继承共有方法
util.inherits(Girl, EventEmitter);
let girl = new Girl();
let cry = () => {
console.log('哭');
}
let drink = () => {
console.log('喝酒');
}
// 绑定对应方法
girl.on('女生失恋', cry);
girl.on('女生失恋', drink);
// 默认状况下是不执行的
// 触发执行
girl.emit('女生失恋');
复制代码
模拟实现发布订阅this
<!--新建文件events.js-->
// 定义一个类
function EventEmitter() {
}
// 导出
module.exports = EventEmitter;
复制代码
// 定义一个类
function EventEmitter() {
}
// 订阅
EventEmitter.prototype.on = function() {
}
// 发布
EventEmitter.prototype.emit = function() {
}
// 导出
module.exports = EventEmitter;
复制代码
{ '女生失恋': ['喝酒fn', '哭fn'] }
:// 定义一个类
function EventEmitter() {
// 维护一个对象
// {
// '女生失恋': ['哭', '喝酒']
// }
this._events = {};
}
// 订阅
EventEmitter.prototype.on = function(type, callback) {
// 若是取不到_events 默认给空对象
if (!this._events){
this._events = {};
}
// 对象中存在
if (this._events[type]) {
this._events[type].push(callback);
} else {
this._events[type] = [callback];
}
}
复制代码
// 发布
EventEmitter.prototype.emit = function(type) {
// 存在数组
if (this._events[type]) {
this._events[type].forEach(fn => {
// 此处的 fn 就是 喝酒, 哭
fn();
});
}
}
复制代码
EventEmitter.prototype.removeListener = function(type, callback) {
// 找到数组中对应方法移除。
if (this._events[type]) {
this._events[type] = this._events[type].filter(fn => {
return fn != callback;
})
}
}
// 外界调用
// 解绑事件
girl.removeListener('女生失恋', cry);
复制代码
当前监听的若是不是 newListener 时候。执行 newListener 方法把当前 type 传递给回调函数,这样外界就能够获取 type 了spa
// 订阅
EventEmitter.prototype.on = function(type, callback) {
if (type !== 'newListener') {
this._events['newListener'].forEach(fn => {
fn(type);
})
}
// 若是取不到_events 默认给空对象
if (!this._events){
this._events = {};
}
// 对象中存在
if (this._events[type]) {
this._events[type].push(callback);
} else {
this._events[type] = [callback];
}
}
// 外界调用
girl.on('newListener', (type) => {
console.log(type);
})
复制代码
// 默认最大监听
EventEmitter.defaultMaxListener = 10;
// 设置最大监听
EventEmitter.prototype.setMaxListeners = function(count) {
this._count = count;
}
// 获取最大监听
EventEmitter.prototype.getMaxListeners = function(count) {
return this._count || EventEmitter.defaultMaxListener;
}
// 获取 eventName
EventEmitter.prototype.eventNames = function() {
return Object.keys(this._events);
}
// 获取监听方法
EventEmitter.prototype.listeners = function(type) {
return this._events[type];
}
// 移除全部监听
EventEmitter.prototype.removeAllListeners = function(type) {
if (type) {
return this._events[type] = [];
};
this._events = {};
}
复制代码
代码:prototype
event.jscode
// 定义一个类
function EventEmitter() {
// 维护一个对象
// {
// '女生失恋': ['哭', '喝酒']
// 'newListener': []
// }
this._events = {};
}
// 订阅
EventEmitter.prototype.addListener = EventEmitter.prototype.on = function(type, callback) {
// 若是取不到_events 默认给空对象
if (!this._events) {
this._events = Object.create(null);
}
if (type !== 'newListener' && this._events['newListener'] && this._events['newListener'].length) {
this._events['newListener'].forEach(fn => {
fn(type);
})
}
// 对象中存在
if (this._events[type]) {
this._events[type].push(callback);
} else {
this._events[type] = [callback];
}
// 若是超限制提示错误
if (this._events[type].length === this.getMaxListeners()) {
console.warn('memory link detected');
}
}
// 发布
EventEmitter.prototype.emit = function(type, ...args) {
// 存在数组
if (this._events[type]) {
this._events[type].forEach(fn => {
// 此处的 fn 就是 喝酒, 哭
fn(...args);
});
}
}
EventEmitter.prototype.removeListener = function(type, callback) {
// 找到数组中对应方法移除。
if (this._events[type]) {
this._events[type] = this._events[type].filter(fn => {
return fn != callback && fn.l !== callback;
})
}
}
// 默认最大监听
EventEmitter.defaultMaxListener = 10;
// 设置最大监听
EventEmitter.prototype.setMaxListeners = function(count) {
this._count = count;
}
// 获取最大监听
EventEmitter.prototype.getMaxListeners = function(count) {
return this._count || EventEmitter.defaultMaxListener;
}
// 获取 eventName
EventEmitter.prototype.eventNames = function() {
return Object.keys(this._events);
}
// 获取监听方法
EventEmitter.prototype.listeners = function(type) {
return this._events[type];
}
// 移除全部监听
EventEmitter.prototype.removeAllListeners = function(type) {
if (type) {
return this._events[type] = [];
};
this._events = {};
}
// once 先绑定 wrap 函数当执行完后从数组中删除。
EventEmitter.prototype.once = function(type, callback) {
// 添加一个包裹函数。
let wrap = (...args) => {
callback(...args);
this.removeListener(type, wrap);
}
// 将callback保存在 wrap.l上
wrap.l = callback;
this.on(type, wrap);
}
// 导出
module.exports = EventEmitter;
复制代码
调用:对象
let EventEmitter = require('./events');
let util = require('util');
// 定义一个类
function Girl() {
// EventEmitter.call(this);
}
// 继承共有方法
util.inherits(Girl, EventEmitter);
let girl = new Girl();
let cry = (a, b) => {
console.log('哭', a, b);
}
let drink = (a, b) => {
console.log('喝酒', a, b);
}
// girl.setMaxListeners(1);
// console.log(girl.getMaxListeners());
girl.on('newListener', (type) => {
// console.log(type, '哈哈哈');
})
// 绑定对应方法
girl.once('女生失恋', cry);
// girl.on('女生失恋', drink);
// 解绑事件
// girl.removeListener('女生失恋', cry);
// 默认状况下是不执行的
// 触发执行
girl.emit('女生失恋', 1, 2);
girl.emit('女生失恋');
girl.emit('女生失恋');
// 获取最大监听
// console.log(EventEmitter.defaultMaxListener);
// 获取 eventNames [ 'newListener', '女生失恋' ]
// console.log(girl.eventNames());
console.log(girl.listeners('女生失恋'));
复制代码