| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- '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;
- };
|