实现EventEmitter类 观察者模式和发布/订购模式

js实现EventEmitter

原生EventEmitter用法

var events = require('events');
const EventEmitter = events.EventEmitter;
const event = new EventEmitter();
event.on('click', (data) => {
    console.log('click+' + data);
});
event.emit('click', 1); // click+1

自己实现 EventEmitter

/*实现了EventEmitter的三个方法 on【订阅】,emit【发送】,off【退订】*/
class EventEmitter {
    constructor() {
        this.events = {};
    }
    on(event, fn) {
        this.events[event] = fn;
    }
    emit(event, ...params) {
        if (this.events[event]) {
            this.events[event](...params);
        } else {
            console.log('您没有订阅该事件');
        }
    }
    off(event) {
        delete this.events[event];
    }
}
const event = new EventEmitter();
event.on('click', (...params) => {
    console.log('click ' + [...params]);
});
event.emit('click', 1, 2); // click 1, 2
event.off('click');
event.emit('click', 1); // 您没有订阅该事件

下面介绍两个不陌生的设计模式

观察者模式和发布订阅模式的区别

参考:https://www.zhihu.com/question/23486749
观察者模式:
观察者A,被观察者B。A注册到B, B有变化,A就随之相应的变化。
【每天早上定牛奶(只能订早上的牛奶)】

实现EventEmitter类 观察者模式和发布/订购模式_第1张图片
111.png

发布订阅模式:
有一个调度中心,不仅仅会调度一种任务
【例如公司的点三餐制度(可以加餐,例如宵夜)】
实现EventEmitter类 观察者模式和发布/订购模式_第2张图片
222.png

上面的时间监听其实是“发布订阅模式”
以一个订牛奶为实际场景。分别实现“观察者模式”和“发布订阅模式”
观察者模式的订奶场景

/*订奶者*/
class Order {
    constructor(name, type) {
        this.name = name;
        this.type = type;
    }
    getMilk(product) { /* type为装牛奶的方式 */
        console.log(`${this.name}得到了一份${this.type}的${product}`);
    }
}
/*订奶人列表*/
class OrderList {
    constructor() {
        this.orderList = [];
    }
    addOrder(obj) {
        this.orderList.push(obj);
    }
    orderNum() {
        return this.orderList.length;
    }
    removeOrder(name) {
        this.orderList = this.orderList.filter((item) => {
            return item.name !== name;
        });
    }
}
/*发奶公司*/
class MilkCompany extends OrderList{
    sendMilk() {
        this.orderList.forEach((item) => {
            item.getMilk('牛奶');
        });
    }
}
const order1 = new Order('张三', '罐装');
const order2 = new Order('李四', '盒装');
const milkCompany = new MilkCompany();
milkCompany.addOrder(order1);
milkCompany.addOrder(order2);
milkCompany.sendMilk();
//张三得到了一份罐装的牛奶
//李四得到了一份盒装的牛奶

发布订阅模式的 场景

/*观察者*/
class Order {
    constructor(name, type) {
        this.name = name;
        this.type = type;
    }
    getOrder(product) { /* */
        console.log(`${this.name}得到了一份${this.type}的${product}`);
    }
}
let uid = 0;
/*订单中介,订奶只是业务之一*/
class OrderManage {
    constructor() {
        this.orderTypes = {};
    }
    addOrderType(type, send) {
        if (!this.orderTypes[type]) {
            this.orderTypes[type] = [];
        }
        this.orderTypes[type].push({
            uid: uid++,
            send,
        });
    }
    removeOrderType(type) {
        delete this.orderTypes[type];
    }
    sendOrder(type, ...params) {
        if (this.orderTypes[type] && this.orderTypes[type].length > 0) {
            this.orderTypes[type].forEach((item) => {
                item.send(...params);
            });
        } else {
            console.log('您未委托我司 管理发送该业务');
        }
    }
}
const orderManage = new OrderManage();
const order1 = new Order('张三', '罐装');
const order2 = new Order('李四', '盒装');
orderManage.addOrderType('milk', (type) => { /*订阅*/
    order1.getOrder(type);
});
orderManage.addOrderType('milk', (type) => {
    order2.getOrder(type);
});
orderManage.sendOrder('milk', '牛奶')  /*发布*/
orderManage.addOrderType('coffee', (type) => {
    order1.getOrder(type);
});
orderManage.addOrderType('coffee', (type) => {
    order2.getOrder(type);
});
orderManage.sendOrder('coffee', '咖啡');
//张三得到了一份罐装的牛奶
//李四得到了一份盒装的牛奶
//张三得到了一份罐装的咖啡
//李四得到了一份盒装的咖啡

你可能感兴趣的:(实现EventEmitter类 观察者模式和发布/订购模式)