发布订阅模式

  • A+
所属分类:Web前端
摘要

————————- End ————————-


本文的创作启发来自于Vue中的EventBus(也有人叫中央事件总线),全文系博主原创,转载请标明出处,如有理解不当之处欢迎各位大佬赐教,谢谢!

本文代码秉承发布订阅模式的思想模拟实现了 Vue中的EvnetBus

那么,上代码!

JS版

class Subscription {     subscriptionStack = {};     on(eventName, callBack) {         if (this.subscriptionStack[eventName]) {             this.subscriptionStack[eventName].callBacks.push(callBack);             callBack(this.subscriptionStack[eventName].value);         } else {             console.error("该接口未注册,请先通过emit方法注册接口,再来监听")             return;         }     }     emit(eventName, value) {         if (this.subscriptionStack[eventName]) {             Reflect.set(this.subscriptionStack[eventName], 'value', value);         } else {             const origin = {                 value,                 callBacks: []             }             const proxyHandle = {                 get(origin, key) {                     return origin[key];                 },                 set(origin, key, value) {                     if (key == 'value' && origin.callBacks.length) {                         origin.callBacks.forEach(callBack => {                             callBack(value);                         })                     }                 }             }             this.subscriptionStack[eventName] = new Proxy(origin, proxyHandle);         }     } } 

Ts版

interface SubscriptionClassInterface {   subscriptionStack: object;   on(eventName: string, callBack: (val: any) => void): void;   emit(eventName: string, value: any): void; }  class Subscription implements SubscriptionClassInterface {   subscriptionStack: object;   on: (eventName: string, callBack: (val: any) => void) => void;   emit: (eventName: string, value: any) => void;    constructor() {     this.subscriptionStack = {};      this.on = (eventName: string, callBack: (val: any) => void) => {       if (this.subscriptionStack[eventName]) {         this.subscriptionStack[eventName].callBacks.push(callBack);         callBack(this.subscriptionStack[eventName].value);       } else {         console.error("该接口未注册,请先通过emit方法注册接口,再来监听");         return;       }     };      this.emit = (eventName: string, value: any) => {       if (this.subscriptionStack[eventName]) {         Reflect.set(this.subscriptionStack[eventName], "value", value);       } else {         const origin = {           value,           callBacks: [],         };         const proxyHandle = {           get(origin, key): any {             return origin[key];           },           set(origin, key, value): any {             if (key == "value" && origin.callBacks.length) {               origin.callBacks.forEach((callBack) => {                 callBack(value);               });             }           },         };         this.subscriptionStack[eventName] = new Proxy(origin, proxyHandle);       }     };   } }  

使用方法:

第一步、

# 创建实例 let s = new Subscription(); 

第二步、

# 发布事件 s.emit(事件名,值) # 举个栗子: s.emit('change',20);  

第三步、

# 订阅事件 s.on(事件名,回调函数) > 此处的事件名一定要和emit中的对应上 # 举个栗子: s.on('change',function(val){ //emit中传入的值在Val中接收到 //这里可以写入相应的逻辑代码 //每当再次调用emit这个回调函数会被自动调用,完成响应式 }) 

------------------------- End -------------------------