js EventBus

Es6

class EventBus {
  constructor() {
    this._events = [];//存储自定义事件
  }

  /**
   * 注册事件和处理函数
   * @param event
   * @param fn
   */
  on(event, fn) {
    if (Array.isArray(event)) {
      for (let i = 0, l = event.length; i < l; i++) {
        this.on(event[i], fn)
      }
    } else {
      // 存在直接push, 不存在创建为空数组再push
      (this._events[event] || (this._events[event] = [])).push(fn)
    }
  }

  /**
   * 注册事件和处理函数,触发一次后销毁
   * @param event
   * @param fn
   */
  once(event, fn) {
    let _self=this;
    function handler() {
      _self.off(event, handler);
      fn.apply(null,arguments);//emit里面调用时会给on方法传参
    }

    handler.fn = fn;//off里面根据这个判断销毁事件
    this.on(event, handler);
  }

  /**
   * 销毁事件和处理函数
   * @param event
   * @param fn
   */
  off(event, fn) {
    //不传参数表示清空所有
    if (!arguments.length) {
      this._events = [];
    }
    //数组循环清空
    if (Array.isArray(event)) {
      for (let i = 0, l = event.length; i < l; i++) {
        this.off(event[i], fn)
      }
    }
    const cbs = this._events[event];
    if (!cbs) {
      return;
    }
    //不传第二参表示清空某事件所有监听函数
    if (arguments.length == 1) {
      this._events[event] = null
    }
    let cb, i = cbs.length
    while (i--) {
      cb = cbs[i]
      if (cb === fn || cb.fn === fn) { //cb.fn===fn用来移除once注册的事件
        cbs.splice(i, 1)
        break
      }
    }
  }

  /**
   * 触发某事件所有回调并带参数
   * @param event
   */
  emit(event) {
    //once删除事件会导致下面循环过程中this._events内fn前移, 所以此处复制成新数组
    let cbs = [...this._events[event]];
    if (cbs) {
      for (let i = 0, l = cbs.length; i < l; i++) {
        try {
          cbs[i].apply(null,[...arguments].slice(1))
        } catch (e) {
          new Error(e, `event handler for "${event}"`)
        }
      }
    }
  }
}

//测试用例
let eb=new EventBus();
eb.once('event1',params=>console.log(11,params));
eb.on('event1',params=>console.log(22,params));
eb.emit('event1',33)

Es5

'use strict';

var _createClass = function () {
  function defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }

  return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);
    if (staticProps) defineProperties(Constructor, staticProps);
    return Constructor;
  };
}();

function _toConsumableArray(arr) {
  if (Array.isArray(arr)) {
    for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
      arr2[i] = arr[i];
    }
    return arr2;
  } else {
    return Array.from(arr);
  }
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var EventBus = function () {
  function EventBus() {
    _classCallCheck(this, EventBus);

    this._events = []; //存储自定义事件
  }

  /**
   * 注册事件和处理函数
   * @param event
   * @param fn
   */


  _createClass(EventBus, [{
    key: 'on',
    value: function on(event, fn) {
      if (Array.isArray(event)) {
        for (var i = 0, l = event.length; i < l; i++) {
          this.on(event[i], fn);
        }
      } else {
        // 存在直接push, 不存在创建为空数组再push
        (this._events[event] || (this._events[event] = [])).push(fn);
      }
    }

    /**
     * 注册事件和处理函数,触发一次后销毁
     * @param event
     * @param fn
     */

  }, {
    key: 'once',
    value: function once(event, fn) {
      var _self = this;

      function handler() {
        _self.off(event, handler);
        fn.apply(null, arguments); //emit里面调用时会给on方法传参
      }

      handler.fn = fn; //off里面根据这个判断销毁事件
      this.on(event, handler);
    }

    /**
     * 销毁事件和处理函数
     * @param event
     * @param fn
     */

  }, {
    key: 'off',
    value: function off(event, fn) {
      //不传参数表示清空所有
      if (!arguments.length) {
        this._events = [];
      }
      //数组循环清空
      if (Array.isArray(event)) {
        for (var _i = 0, l = event.length; _i < l; _i++) {
          this.off(event[_i], fn);
        }
      }
      var cbs = this._events[event];
      if (!cbs) {
        return;
      }
      //不传第二参表示清空某事件所有监听函数
      if (arguments.length == 1) {
        this._events[event] = null;
      }
      var cb = void 0,
        i = cbs.length;
      while (i--) {
        cb = cbs[i];
        if (cb === fn || cb.fn === fn) {
          //cb.fn===fn用来移除once注册的事件
          cbs.splice(i, 1);
          break;
        }
      }
    }

    /**
     * 触发某事件所有回调并带参数
     * @param event
     */

  }, {
    key: 'emit',
    value: function emit(event) {
      //once删除事件会导致下面循环过程中this._events内fn前移, 所以此处复制成新数组
      var cbs = [].concat(_toConsumableArray(this._events[event]));
      if (cbs) {
        for (var i = 0, l = cbs.length; i < l; i++) {
          try {
            cbs[i].apply(null, [].concat(Array.prototype.slice.call(arguments)).slice(1));
          } catch (e) {
            new Error(e, 'event handler for "' + event + '"');
          }
        }
      }
    }
  }]);

  return EventBus;
}();


//测试用例
var eb = new EventBus();
eb.once('event1', function (params) {
  return console.log(11, params);
});
eb.on('event1', function (params) {
  return console.log(22, params);
});
eb.emit('event1', 33);

本文地址:

https://www.cnblogs.com/stumpx/p/15136761.html

==

原文地址:https://www.cnblogs.com/stumpx/p/15136761.html