backbone event 事件订阅 和发布 源码小读

nodejs有eventEmitter 类,想到backbone  有个event模块 可以对对象做事件绑定和触发,是backbone的核心模块。

backbone event模块

  • on 添加自定义事件
  • off 删除自定义事件
  • trigger 派发自定义事件
  • once 添加只执行一次的自定义事件 (内部依赖于_.once)
  • listenTo 添加一个观察对象
  • listenToOnce 添加一个仅执行一次的观察对象
  • stopListening 删除添加的观察对象
------------------------------------
on:绑定事件的方法
   on: function(name, callback, context) {
      if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
      this._events || (this._events = {});
      var events = this._events[name] || (this._events[name] = []);
      events.push({callback: callback, context: context, ctx: context || this});
      return this;
    },

在当前的bancbone.event 的实例上添加_events 属性,所有通过backbone.events 订阅的事假, 都在这个哈希表上。

_events 的结构,先哈希后数组,其中 ctx, context赋值回调函数的this

    _events={
        eventName:[handlerObj,handlerObj,handlerObj],
        eventName:[{callback:function(){}, context: Object, ctx: Object}]
    }

trigger:   

  trigger: function(name) {
      if (!this._events) return this;
      var args = slice.call(arguments, 1);  /*获得传入callback的参数类型数组 */
      if (!eventsApi(this, 'trigger', name, args)) return this;
      var events = this._events[name];
      var allEvents = this._events.all;
      if (events) triggerEvents(events, args);//triggerEvents 针对 apply  call做了性能优化
      if (allEvents) triggerEvents(allEvents, arguments); //如果 当前实例有事件名为all的事件,在触发完指定的name事件后还会触发all的事件
      return this;
    }

  

triggerEvents :执行_events[name]中的方法
官方解释因为call的性能比apply好 ,所以三个参数以下都使用call,三个参数以上才使用apply,大神的要求就是这么高
  var triggerEvents = function(events, args) {
    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
    switch (args.length) {
      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx);return;
      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
    }
  };

  

原文地址:https://www.cnblogs.com/breakdown/p/4281354.html