https://github.com/developit/mitt

    1. // @flow
    2. // An event handler can take an optional event argument
    3. // and should not return a value
    4. type EventHandler = (event?: any) => void;
    5. type WildCardEventHandler = (type: string, event?: any) => void
    6. // An array of all currently registered event handlers for a type
    7. type EventHandlerList = Array<EventHandler>;
    8. type WildCardEventHandlerList = Array<WildCardEventHandler>;
    9. // A map of event types and their corresponding event handlers.
    10. type EventHandlerMap = {
    11. '*'?: WildCardEventHandlerList,
    12. [type: string]: EventHandlerList,
    13. };
    14. /** Mitt: Tiny (~200b) functional event emitter / pubsub.
    15. * @name mitt
    16. * @returns {Mitt}
    17. */
    18. export default function mitt(all: EventHandlerMap) {
    19. all = all || Object.create(null);
    20. return {
    21. /**
    22. * Register an event handler for the given type.
    23. *
    24. * @param {String} type Type of event to listen for, or `"*"` for all events
    25. * @param {Function} handler Function to call in response to given event
    26. * @memberOf mitt
    27. */
    28. on(type: string, handler: EventHandler) {
    29. (all[type] || (all[type] = [])).push(handler);
    30. },
    31. /**
    32. * Remove an event handler for the given type.
    33. *
    34. * @param {String} type Type of event to unregister `handler` from, or `"*"`
    35. * @param {Function} handler Handler function to remove
    36. * @memberOf mitt
    37. */
    38. off(type: string, handler: EventHandler) {
    39. if (all[type]) {
    40. all[type].splice(all[type].indexOf(handler) >>> 0, 1);
    41. }
    42. },
    43. /**
    44. * Invoke all handlers for the given type.
    45. * If present, `"*"` handlers are invoked after type-matched handlers.
    46. *
    47. * Note: Manually firing "*" handlers is not supported.
    48. *
    49. * @param {String} type The event type to invoke
    50. * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler
    51. * @memberOf mitt
    52. */
    53. emit(type: string, evt: any) {
    54. (all[type] || []).slice().map((handler) => { handler(evt); });
    55. (all['*'] || []).slice().map((handler) => { handler(type, evt); });
    56. }
    57. };
    58. }
    1. /** Mitt: Tiny (~200b) functional event emitter / pubsub.
    2. * @name mitt
    3. * @returns {Mitt}
    4. */
    5. function mitt (all) {
    6. all = all || Object.create(null)
    7. return {
    8. on (type, handler) {
    9. if (!all[type]) {
    10. all[type] = []
    11. }
    12. all[type].push(handler)
    13. },
    14. off (type, handler) {
    15. if (all[type]) {
    16. // x >>> 0本质上就是保证x有意义(为数字类型),
    17. // 且为正整数,在有效的数组范围内(0 ~ 0xFFFFFFFF),
    18. // 且在无意义的情况下缺省值为0。
    19. // -1 >>> 0 === 4294967295
    20. all[type].splice(all[type].indexOf(handler) >>> 0, 1)
    21. }
    22. },
    23. emit (type, evt) {
    24. (all[type] || []).slice().map(function (handler) {
    25. handler(evt)
    26. });
    27. // 以“*”为名称的事件监听器会在任何事件触发后一起触发
    28. (all['*'] || []).slice().map(function (handler) {
    29. handler(type, evt)
    30. })
    31. }
    32. }
    33. }