How to create and trigger events on objects rather than elements

264 Views Asked by At

I'm writing a small library that essentially polls a site for data, and is then supposed to notify a consumer when it matches. In C# I'd use events, which are actually multicast delegates. I've written my own multicast delegate in javascript before, but I figure there has to be a better way.

A consumer should register a callback which should be called when data is available. Something like this:

window.MyLibrary.dataAvailable(function(data) {
    // do something with data
});

In the background MyLibrary is polling for data. When it finally has something that matches, it should execute the registered function(s). Multiple functions should be able to be registered and probably unregistered too.

CustomEvent is very very close to what I want. The problem with CustomEvent is that the event has to be raised on an element - it can't be raised on an object. That is, this wouldn't work:

var event = new CustomEvent('dataAvailable', { data: 'dynamic data' });

window.MyLibrary.addEventListener('dataAvailable', function (e) { 
    // do something with e.data
}, false);

// From somewhere within MyLibrary
this.dispatchEvent(event, data);

How do you register handlers on objects in javascript? I need to support the usual browsers and IE11+. Ideally I wouldn't be pulling in a library to do any of this. jQuery will be available on the page and can be used if that would make things easier.

For reference, this is the Multicast Delegate implementation I've used in the past:

function MulticastDelegate(context) {
    var obj = context || window,
        handlers = [];

    this.event = {
        subscribe: function (handler) {
            if (typeof (handler) === 'function') {
                handlers.push(handler);
            }
        },
        unsubscribe: function (handler) {
            if (typeof (handler) === 'function') {
                handlers.splice(handlers.indexOf(handler), 1);
            }
        }
    };

    this.execute = function () {
        var args = Array.prototype.slice.call(arguments);
        for (var i = 0; i < handlers.length; i++) {
            handlers[i].apply(obj, args);
        }
    };
}

var myEvent = new MulticastDelegate();
myEvent.event.subscribe(function(data) { ... }); // handler 1
myEvent.event.subscribe(function(data) { ... }); // handler 2
myEvent.execute(some_data);
0

There are 0 best solutions below