Last active
August 29, 2015 14:21
-
-
Save nariyu/57a2b9408dd63865458f to your computer and use it in GitHub Desktop.
EventEmitter (ES6)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// イベントリスナーの入れ物 | |
let listenerMap = new Map; | |
/** | |
EventEmitter クラス | |
*/ | |
export default class EventEmitter { | |
/** | |
コンストラクタ | |
*/ | |
constructor() { | |
} | |
/** | |
イベント発射 | |
@method trigger | |
@param {String} type 送信するイベントタイプ | |
*/ | |
trigger() { | |
let args = Array.prototype.slice.call(arguments); | |
let type = args.shift(); | |
let data; | |
if (typeof type === 'string') { | |
data = args.shift(); | |
} else { | |
data = type; | |
type = type.type; | |
} | |
let namespace = ''; | |
if (type.indexOf('.') > 0) { | |
[type, namespace] = type.split('.'); | |
} | |
if (!data) data = {}; | |
data.type = type; | |
let listeners = listenerMap.get(this); | |
if (!listeners) { | |
listeners = {} | |
listenerMap.set(this, listeners); | |
} | |
let callbacks = []; | |
for (let lType in listeners) { | |
let lCallback = listeners[lType]; | |
if (namespace === '' && lType.indexOf('.') > 0) | |
[lType, ] = lType.split('.'); | |
if (lType === type) | |
callbacks = callbacks.concat(lCallback); | |
} | |
for (let callback of callbacks) | |
callback.call(this, data); | |
} | |
emit() { | |
this.trigger.apply(this, Array.prototype.slice.call(arguments)); | |
} | |
/** | |
イベントを待ち受ける | |
@method on | |
@param {String} type 受信を待ち受けたいイベントタイプ | |
@param {Function} callback 受信した時に実行したい処理 | |
*/ | |
on(type, callback, context) { | |
if (callback && context) | |
callback = callback.bind(context); | |
let listeners = listenerMap.get(this); | |
if (!listeners) { | |
listeners = {} | |
listenerMap.set(this, listeners); | |
} | |
if (!listeners[type]) | |
listeners[type] = []; | |
listeners[type].push(callback); | |
} | |
addEventListener(type, callback) { | |
this.on(type, callback); | |
} | |
/** | |
イベント待ち受けを解除する | |
@method off | |
@param {String} type 受信を解除したいイベントタイプ | |
@param {Function} callback 受信を解除したい処理 | |
*/ | |
off(type, callback, context) { | |
if (callback && context) | |
callback = callback.bind(context); | |
let listeners = listenerMap.get(this); | |
if (!listeners) { | |
listeners = {} | |
listenerMap.set(this, listeners); | |
} | |
let namespace = ''; | |
if (type.indexOf('.') > 0) | |
[type, namespace] = type.split('.'); | |
if (!listeners.hasOwnProperty(type)) { | |
return | |
} | |
// callback がない場合は、type のすべてのリスナーを解除 | |
if (!callback) { | |
if (namespace === '') { | |
for (let lType in listeners) { | |
let lCallback = listeners[lType]; | |
let olType = lType; | |
if (lType.indexOf('.') > 0) | |
[lType, ] = lType.split('.'); | |
if (lType === type) | |
delete listeners[olType]; | |
} | |
} else { | |
delete listeners[type + '.' + namespace]; | |
} | |
// | |
} else { | |
let i = 0; | |
let arr = listeners[type]; | |
let len = arr.length; | |
while (i < len) { | |
let cb = arr[i]; | |
if (cb == callback) | |
if (len === 1) | |
delete listeners[type]; | |
else | |
arr.splice(i, 1); | |
break; | |
i++; | |
} | |
} | |
let keys = []; | |
for (let key in listeners) { | |
keys.push(key); | |
} | |
if (keys.length == 0) { | |
listenerMap.delete(this); | |
} | |
} | |
removeEventListener(type, callback) { | |
this.off(type, callback); | |
} | |
/** | |
すべてのイベントリスナーを削除する | |
@method removeAllListeners | |
*/ | |
removeAllListeners() { | |
listenerMap.delete(this); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment