buster.eventEmitter

Version
0.2.0 (2011-03-14)
Module
require("buster-event-emitter");
In browsers
buster.eventEmitter;

A simple pubsub implementation for JavaScript inspired by the node.js EventEmitter API.

Methods

create()

Creates and returns a new "blank" event emitter.

// Using create
var obj = buster.eventEmitter.create();
// Same thing
var obj2 = Object.create(
               buster.eventEmitter);

Creating event emitter APIs

buster-event-emitter is designed to power your custom event emitters. There are a few ways you might want to do this. The simplest approach is to create a new event emitter and add properties to it:

var eventedLogger = buster.eventEmitter.create();
eventedLogger.LEVEL_ERROR = 0;
eventedLogger.LEVEL_WARN = 1;
eventedLogger.LEVEL_INFO = 2;
eventedLogger.level = eventedLogger.LEVEL_INFO;
eventedLogger.info = function () {
    if (this.level >= this.LEVEL_INFO) {
        this.emit("info", Array.prototype.slice.call(arguments));
    }
};
eventedLogger.warn = function () {
    if (this.level >= this.LEVEL_WARN) {
        this.emit("warn", Array.prototype.slice.call(arguments));
    }
};
eventedLogger.error = function () {
    if (this.level >= this.LEVEL_ERROR) {
        this.emit("error", Array.prototype.slice.call(arguments));
    }
};

This API could be used as such:

var logger = Object.create(eventedLogger);
logger.on("info", function () {
    console.log.apply(console, arguments);
});

An alternative way of creating a custom event emitter is using buster.extend, which copies properties between objects:

var eventedLogger = buster.extend(buster.eventEmitter.create(), {
    LEVEL_ERROR: 0,
    LEVEL_WARN: 1,
    LEVEL_INFO: 2,
    level: 2,
    info: function () {
        if (this.level >= this.LEVEL_INFO) {
            this.emit("info", Array.prototype.slice.call(arguments));
        }
    },
    warn: function () {
        if (this.level >= this.LEVEL_WARN) {
            this.emit("warn", Array.prototype.slice.call(arguments));
        }
    },
    error: function () {
        if (this.level >= this.LEVEL_ERROR) {
            this.emit("error", Array.prototype.slice.call(arguments));
        }
    }
};

on(event, listener[, thisObj])

Adds an event listener for the specified event. event is a string, and the event listener must be a function. When the event is emitted, the listener will be called with whatever arguments were emitted.

var emitter = buster.eventEmitter.create();
emitter.on("message", function () { /* ... */ });

If a thisObj is passed, the method will be called with this object as its this value.

var logger = {
    log: function () {
        for (var i = 0, l = arguments.length; i < l; ++i) {
            this.io.puts(arguments[i]);
        }
    }
};
logger.io = require("sys");
var emitter = buster.eventEmitter.create();
emitter.on("message", logger.log, logger);

addListener(event, listener[, thisObj])

Alias for on.

var emitter = buster.eventEmitter.create();
emitter.addListener("message", function () { /* ... */ });

hasListener(event, listener[, thisObj])

Returns true if the emitter has the listener in question.

var emitter = buster.eventEmitter.create();
var listener = function () {};
emitter.on("message", listener);
emitter.hasListener("message", listener); // true
emitter.hasListener("message", function () {}); // false
emitter.on("click", logger.log, logger);
emitter.hasListener("click", logger.log); // false
emitter.hasListener("click", logger.log, logger); // true

emit(event[, data1, data2, ...])

Notifies all listeners of event of new data. Event is a string. Any arguments passed after the event name is passed along to the listeners.

var listener = function () {
    console.log(Array.prototype.slice.call(arguments));
};
var emitter = buster.eventEmitter.create();
emitter.on("some-event", listener);
emitter.emit("some-event", 2, 3, 4, 5); // Listener prints "[2, 3, 4, 5]"

bind(object[, events])

Binds methods on an object as event listeners, ensuring the methods are called with the proper this object.

If no events is passed, all the object's methods will be bound to events with the same name:

var obj = {
    message: function () {},
    connection: function () {},
    disconnect: function () {}
};
// Using bind
emitter.bind(obj);
// emitter.on equivalent
emitter.on("message", obj.message, obj);
emitter.on("connection", obj.connection, obj);
emitter.on("disconnect", obj.disconnect, obj);

If events is an array of strings, only those methods will be bound to their corresponding events:

var o = {
    message: function () {},
    connect: function () {},
    disconnect: function () {}
};
// Using bind
emitter.bind(o, ["message", "connect"]);
// emitter.on equivalent
emitter.on("message", o.message, o);
emitter.on("connect", o.connect, o);

If events is an object, the keys will be used as events and their string values method names. This way you can bind methods as event listeners and name methods differently from events:

var o = {
    onMessage: function () {},
    onConnection: function () {},
    onDisconnect: function () {}
};
// Using bind
emitter.bind(o, {
    "message": "onMessage",
    "connection": "onConnection"
});
// emitter.on equivalent
emitter.on("message", o.onMessage, o);
emitter.on("connection", o.onConnection, o);