事件消息通知 (ts版)

246 阅读1分钟

废话不多说直接上代码 emitter.ts


interface Callbacks {
    [key: string]: Function[]
}
 class Emitter {
    _callbacks: Callbacks = {}
    constructor() {
        // return id
    }
    
    new() {
        return new Emitter()
    }

    on(event: string, fn: any) {
        fn.fn=0;
        (this._callbacks[event] = this._callbacks[event] || [])
            .push(fn);
        return this;
    }

    once(event: string, fn: Function) {

        var self = this;

        function on(this: any) {
            self.off(event, on);
            fn.apply(this, arguments);
        }

        on.fn = fn;
        this.on(event, on);
        return this;
    }

    off(event: string, fn: Function) {
        this._callbacks = this._callbacks || {};

        //off所有事件
        if (0 == arguments.length) {
            this._callbacks = {};
            return this;
        }

        // off 指定事件集合
        var callbacks = this._callbacks[event];
        if (!callbacks) return this;

       
        if (1 == arguments.length) {
            delete this._callbacks[event];
            return this;
        }

        // off指定事件集合的某个事件
        var cb:any;
        for (var i = callbacks.length-1; i >=0; i--) {
            cb = callbacks[i];
            if (cb === fn || cb.fn === fn) {
                callbacks.splice(i, 1);
                break;
            }
        }
        return this;
    }


    emit(event: string) {
        var args = [].slice.call(arguments, 1),
            callbacks = this._callbacks[event];

        if (callbacks) {
            callbacks = callbacks.slice(0);
            for (var i = 0, len = callbacks.length; i < len; ++i) {
                callbacks[i].apply(this, args);
            }
        }

        return this;
    };
    listeners(event: string) {
        this._callbacks = this._callbacks || {};
        return this._callbacks[event] || [];
    }
    hasListeners(event: string) {
        return !!this.listeners(event).length;
    };
}

export default new Emitter()

使用:

//a.ts
import Emitter from "./emitter.ts"
Emitter.on("msg",function(msg){
    console.log("trigger on",msg)
})

//b.ts
import Emitter from "./emitter.ts"
Emitter.emit("msg","message from b")

附上js版

function Emitter(obj) {
  // if (obj) return mixin(obj);

}

/**
 * Mixin the emitter properties.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

// function mixin(obj) {
//   for (var key in Emitter.prototype) {
//     obj[key] = Emitter.prototype[key];
//   }
//   return obj;
// }

/**
 * Listen on the given `event` with `fn`.
 *
 * @param {String} event
 * @param {Function} fn
 * @return {Emitter}
 * @api public
 */
Emitter.new = function () {
  return new Emitter()
}
Emitter.prototype.on =
  Emitter.prototype.addEventListener = function (event, fn) {
    this._callbacks = this._callbacks || {};
    (this._callbacks[event] = this._callbacks[event] || [])
    .push(fn);
    return this;
  };

/**
 * Adds an `event` listener that will be invoked a single
 * time then automatically removed.
 *
 * @param {String} event
 * @param {Function} fn
 * @return {Emitter}
 * @api public
 */

Emitter.prototype.once = function (event, fn) {
  var self = this;
  this._callbacks = this._callbacks || {};

  function on() {
    self.off(event, on);
    fn.apply(this, arguments);
  }

  on.fn = fn;
  this.on(event, on);
  return this;
};

/**
 * Remove the given callback for `event` or all
 * registered callbacks.
 *
 * @param {String} event
 * @param {Function} fn
 * @return {Emitter}
 * @api public
 */

Emitter.prototype.off =
  Emitter.prototype.removeListener =
  Emitter.prototype.removeAllListeners =
  Emitter.prototype.removeEventListener = function (event, fn) {
    this._callbacks = this._callbacks || {};

    // all
    if (0 == arguments.length) {
      this._callbacks = {};
      return this;
    }

    // specific event
    var callbacks = this._callbacks[event];
    if (!callbacks) return this;

    // remove all handlers
    if (1 == arguments.length) {
      delete this._callbacks[event];
      return this;
    }

    // remove specific handler
    var cb;
    for (var i = 0; i < callbacks.length; i++) {
      cb = callbacks[i];
      if (cb === fn || cb.fn === fn) {
        callbacks.splice(i, 1);
        break;
      }
    }
    return this;
  };

/**
 * Emit `event` with the given args.
 *
 * @param {String} event
 * @param {Mixed} ...
 * @return {Emitter}
 */

Emitter.prototype.emit = function (event) {
  this._callbacks = this._callbacks || {};
  var args = [].slice.call(arguments, 1),
    callbacks = this._callbacks[event];

  if (callbacks) {
    callbacks = callbacks.slice(0);
    for (var i = 0, len = callbacks.length; i < len; ++i) {
      callbacks[i].apply(this, args);
    }
  }

  return this;
};

/**
 * Return array of callbacks for `event`.
 *
 * @param {String} event
 * @return {Array}
 * @api public
 */

Emitter.prototype.listeners = function (event) {
  this._callbacks = this._callbacks || {};
  return this._callbacks[event] || [];
};

/**
 * Check if this emitter has `event` handlers.
 *
 * @param {String} event
 * @return {Boolean}
 * @api public
 */

Emitter.prototype.hasListeners = function (event) {
  return !!this.listeners(event).length;
};