设计模式

24 阅读1分钟

设计模式

使用Proxy实现观察者模式

实现observable和observe这两个函数

const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
const observable = obj => new Proxy(obj, {set});

function set(target, key, value, receiver) {
  const result = Reflect.set(target, key, value, receiver);
  queuedObservers.forEach(observer => observer());
  return result;
}

实现发布订阅模式

class EventBus {
  constructor() {
    /**
     * 构造函数需要存储的 event 事件
     */
    this.events = this.events || new Object()
  }
}

/**
 * @name emit
 * @description 触发事件
 * @param {*} type 事件类型
 * @param  {...any} args 参数
 */
EventBus.prototype.emit = function(type, ...args) {
  const eventFuncs = this.events[type]
  if (Array.isArray(eventFuncs)) {
    for (let index = 0; index < eventFuncs.length; index++) {
      eventFuncs[index].apply(this, args)
    }
  } else {
    eventFuncs.apply(this, args)
  }
}

/**
 * @name addEventListener
 * @description 增加监听函数
 * @param {*} type
 * @param {*} fun
 */
EventBus.prototype.addListener = function(type, func) {
  const eventFuncs = this.events[type]
  if (!eventFuncs) {
    this.events[type] = [func]
  } else {
    eventFuncs.push(func)
  }
}

/**
 * @name removeListener
 * @description 删除监听事件
 * @param {*} type
 */
EventBus.prototype.removeListener = function(type, func) {
  if (this.events[type]) {
    const eventFuncs = this.events[type]
    if (Array.isArray(eventFuncs)) {
      if (func) {
        const funcIndex = eventFuncs.findIndex(eventFunc => func === eventFunc)
        if (funcIndex !== -1) {
          eventFuncs.splice(funcIndex, 1)
        } else {
          console.warn(`eventBus may remove unexit func(${type})`)
        }
      } else {
        delete eventFuncs[type]
      }
    } else {
      delete eventFuncs[type]
    }
  }
}

const eventBus = new EventBus()
export default eventBus