55 lines
1.4 KiB
JavaScript
55 lines
1.4 KiB
JavaScript
'use strict';
|
|
|
|
var atoa = require('atoa');
|
|
var debounce = require('./debounce');
|
|
|
|
module.exports = function emitter (thing, options) {
|
|
var opts = options || {};
|
|
var evt = {};
|
|
if (thing === undefined) { thing = {}; }
|
|
thing.on = function (type, fn) {
|
|
if (!evt[type]) {
|
|
evt[type] = [fn];
|
|
} else {
|
|
evt[type].push(fn);
|
|
}
|
|
return thing;
|
|
};
|
|
thing.once = function (type, fn) {
|
|
fn._once = true; // thing.off(fn) still works!
|
|
thing.on(type, fn);
|
|
return thing;
|
|
};
|
|
thing.off = function (type, fn) {
|
|
var c = arguments.length;
|
|
if (c === 1) {
|
|
delete evt[type];
|
|
} else if (c === 0) {
|
|
evt = {};
|
|
} else {
|
|
var et = evt[type];
|
|
if (!et) { return thing; }
|
|
et.splice(et.indexOf(fn), 1);
|
|
}
|
|
return thing;
|
|
};
|
|
thing.emit = function () {
|
|
var args = atoa(arguments);
|
|
return thing.emitterSnapshot(args.shift()).apply(this, args);
|
|
};
|
|
thing.emitterSnapshot = function (type) {
|
|
var et = (evt[type] || []).slice(0);
|
|
return function () {
|
|
var args = atoa(arguments);
|
|
var ctx = this || thing;
|
|
if (type === 'error' && opts.throws !== false && !et.length) { throw args.length === 1 ? args[0] : args; }
|
|
et.forEach(function emitter (listen) {
|
|
if (opts.async) { debounce(listen, args, ctx); } else { listen.apply(ctx, args); }
|
|
if (listen._once) { thing.off(type, listen); }
|
|
});
|
|
return thing;
|
|
};
|
|
};
|
|
return thing;
|
|
};
|