发布订阅模式下的事件BUS

// 事件bus,不考虑事件延迟订阅的情况,后端可以用promise替代,此脚本在于简化前端异步的情况;
// 此处没有创建事件的命名空间,请使用者自行管理自定义事件名作为命名空间;
// 后绑定的先执行

var Event = (function() {
  var clientList = {};
  var listen = null;
  var trigger = null;
  var remove = null;
  var one = null;

  // 事件绑定,可以重复绑定相同的事件,触发时会全部触发
  // 注意绑定的事件最好不要用匿名函数,事件移除不会移除匿名函数
  listen = function(key, fn) {
    if (!clientList[key]) {
      clientList[key] = [];
    }
    clientList[key].push(fn);
  }

  // 事件触发
  trigger = function() {
    var key = Array.prototype.shift.call(arguments);
    var fns = clientList[key];
    if (!fns || fns.length === 0) {
      return false;
    }
    for (var i = fns.length - 1, fn; i >= 0; i--) {
      fn = fns[i];
      fn.apply(this, arguments);
    }
  }

  // 移除绑定
  remove = function(key, fn) {
    var fns = clientList[key];
    if (!fns) { // 未绑定对应事件
      return false
    }
    if (!fn) { // 清除key绑定的全部事件
      fns && (fns.length = 0)
    } else {
      for (var l = fns.length - 1; l >= 0; l--) {
        var _fn = fns[l];
        if (_fn == fn) {
          fns.splice(l, 1);
        }
      }
    }
  }

  // 绑定一次
  one = function(key, fn) {
      var _self = this;
      var once = fn;
      var handler = function() {
          once.apply(this, arguments);
          _self.remove(key, handler)
      }
      _self.listen(key, handler)
  }

  return {
    listen: listen,
    one: one,
    trigger: trigger,
    remove: remove
  }
})();

module.exports = Event;

THE END!