Skip to content

Instantly share code, notes, and snippets.

@teramako
Last active December 12, 2015 09:09
Show Gist options
  • Save teramako/4749384 to your computer and use it in GitHub Desktop.
Save teramako/4749384 to your computer and use it in GitHub Desktop.
何となく Node.js 的な EventEmitter を実装してみた。 ES.next とか使いまくりで普通じゃ使えないけど。

#Example

function Foo () {
  EventEmitter.call(this);
}
Foo.prototype = mixin(Object.create(EventEmitter.prototype), {
  doSomeThing: function () {
    var data = {};
    //....
    this.emit("doneSomeThing", data)
  }
});

var f = new Foo();
f.on("doneSomeThing", function(data){
  alert(data);
});
function mixin (aTarget, aSource) {
for (var key of Object.getOwnPropertyNames(aSource)) {
let desc = Object.getOwnPropertyDescriptor(aSource, key);
desc.enumerable = false;
Object.defineProperty(aTarget, key, desc);
}
return aTarget;
}
/**
* @class EventEmitter {{{1
*/
function EventEmitter() {
this.listeners = new Map;
}
mixin(EventEmitter.prototype,
/** @lends EventEmitter.prototype */
{
emit: function EventEmitter_emit (aType, aData= null) {
if (!this.listeners.has(aType))
return;
for (let callback of this.listeners.get(aType)) {
try {
if (typeof callback === "function")
callback.call(this, aType, aData);
else
callback.handleEvent(aType, aData);
} catch(e) {
console.error(e);
}
}
},
addListener: function EventEmitter_addListener (aType, aCallback) {
if (typeof aCallback !== "function" &&
(typeof aCallback !== "object" || typeof aCallback.handleEvent !== "function"))
throw TypeError("callback is not callable.");
if (this.listeners.has(aType))
this.listeners.get(aType).add(aCallback);
else
this.listeners.set(aType, new Set([aCallback]));
return this;
},
on: function EventEmitter_on (aType, aCallback) {
this.addListener(aType, aCallback);
return this;
},
once: function EventEmitter_once (aType, aCallback) {
if (typeof aCallback !== "function" &&
(typeof aCallback !== "object" || typeof aCallback.handleEvent !== "function"))
throw TypeError("callback is not callable.");
this.addListener(aType, function once(type, data) {
this.removeEventListener(type, once);
if (typeof aCallback === "function")
aCallback.call(this, type, data);
else
aCallback.handleEvent(type, data);
});
return this;
},
removeListener: function EventEmitter_removeListener (aType, aCallback) {
var funcs = this.listeners.get(aType);
if (funcs)
return funcs.delete(aCallback);
return false;
},
removeAllListeners: function EventEmitter_removeAllListeners (aType) {
if (aType)
this.listeners.delete(aType);
else {
for (let [type] of this.listeners)
this.listeners.delete(type);
}
return this;
},
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment