mleibman / SlickGrid

A lightning fast JavaScript grid/spreadsheet
http://wiki.github.com/mleibman/SlickGrid
MIT License
6.81k stars 1.98k forks source link

Event.notify : notify loop breaks if a handler removes itself #1001

Open ghost opened 10 years ago

ghost commented 10 years ago

I use an event handler which removes itself (I want it to execute only once). However, this causes my second event handler to never be called:

var event = new Slick.Event();

var handler1 = function() {
    alert(1);
    event.unsubscribe(handler1);  // makes sure that this handler will not be called again
};
event.subscribe(handler1);

var handler2 = function() {
    alert(2);
};
event.subscribe(handler2);

event.notify();

I expect both handlers to be called, but handler2 is never called.

The problem is that unsubscribe can modify the handler list while Event.notify is iterating over it. Here is a solution that works for me: in Event.notify (slick.core.js), replace this

      for (var i = 0; i < handlers.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) {
        returnValue = handlers[i].call(scope, e, args);
      }

by this

      var handlersCopy = handlers.slice();
      for (var i = 0; i < handlersCopy.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) {
        returnValue = handlersCopy[i].call(scope, e, args);
      }