Skip to content

Instantly share code, notes, and snippets.

@DScheglov
Last active November 13, 2017 08:59
Show Gist options
  • Save DScheglov/abfb8c6756fd73f8e583270f4a02ecc4 to your computer and use it in GitHub Desktop.
Save DScheglov/abfb8c6756fd73f8e583270f4a02ecc4 to your computer and use it in GitHub Desktop.
EventEmitter - functional style
// --- EventEmitter Factory Implementation ---
const { call, numberCalls, removeItem, append } = require('./helpers');
const unsibsribe = (_handlers, event, handler) => {
_handlers[event] = removeItem(_handlers[event], handler);
};
const on = _handlers => (event, handler) => {
_handlers[event] = append(_handlers[event], handler);
return () => unsibsribe(_handlers, event, handler);
};
const once = _handlers => (event, handler) => on(_handlers)(event,
function _handler(...args) {
unsibsribe(_handlers, event, _handler);
return handler(...args);
}
);
const emit = _handlers => (event, ...args) => (
numberCalls(_handlers[event], call(args)) > 0
);
const createEventEmitter = (handlers = {}) => ({
on: on(handlers),
once: once(handlers),
emit: emit(handlers),
});
module.exports = { createEventEmitter };
// --- HELPERS ---
const call = args => func => func(...args);
const numberCalls = (funcs, mapper) => (
funcs && funcs.length ? funcs.map(mapper).length : 0
);
const removeItemAtIndex = (arr, index) => (
index < 0 ? arr : arr.slice(0, index).concat(arr.slice(index + 1))
);
const removeItem = (arr, item) => (
arr && arr.length ? removeItemAtIndex(arr, arr.indexOf(item)) : arr
);
const append = (arr, item) => (
arr && arr.concat(item) || [item]
);
module.exports = { call, numberCalls, removeItem, append };
// --- createEventEmitter - Usage Sample ---
const { createEventEmitter } = require('./event-emitter');
const eventEmitter = createEventEmitter();
eventEmitter.once('click', (...args) => console.log('First click: ', args));
eventEmitter.on('click', (...args) => console.log('Every click: ', args));
console.log('-----------------');
console.log(
'Event handled:', eventEmitter.emit('click', 1)
);
// -----------------
// First click: [ 1 ]
// Every click: [ 1 ]
// Event handled: true
console.log('-----------------');
console.log(
'Event handled:', eventEmitter.emit('click', 1, 2)
);
// -----------------
// Every click: [ 1, 2 ]
// Event handled: true
console.log('-----------------');
console.log(
'Event handled:', eventEmitter.emit('click', 1, 2, 3)
);
// -----------------
// Every click: [ 1, 2, 3 ]
// Event handled: true
console.log('-----------------');
console.log(
'Event handled:', eventEmitter.emit('hello', 'hello')
);
// -----------------
// Event handled: false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment