Helper function that creates an object that can serve as an event source that is used in an API-object property.
Events are all over the place in Javascript, with several major themes:
-
Specific DOM on- event handlers (e.g. onopen, onerror, onclose, onmessage, onclick,...)
See https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers -
Generalized DOM events (EventTarget: addEventListener, removeEventListener, dispatchEvent)
See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget -
Generalized node.js events (EventEmitter: on, once, emit, removeListener,... - a large API)
See https://nodejs.org/dist/latest-v11.x/docs/api/events.html
We only need a very limited subset of those features. Nether things like event bubbling nor lots of different API functions to subscribe and control events are necessary. The specialized (exactly one per event type) "on-" event handlers, without event names (i.e. they are implicitly named by the property they are made available under) comes closest, but is too limited, since 1) it allows only one handler, 2) accidentally overwriting an existing handler is possible, making some kinds of code errors harder to find.
Instead, we use an event source that allows more than one event handler, but which does not use a
special Event
class and has only a limited set of API functions. In addition, each event
source (object) will be responsible for exactly one kind of event only, just like the
specialized DOM "on-" event types.
The goal is to expose an appropriately named event source object with methods to subscribe and unsubscribe to events for that event. The method to emit events should not be available on the event source object exposed as part of an API, but remain visible only to the code hidden behind that API.
- Source:
Example
function createSomethingAsynchronous () {
// The two OneEventSource objects REMAIN PRIVATE
const onDataEventSource = createEventSource();
const onErrorEventSource = createEventSource();
// If this functionality is needed
onDataEventSource.onListenerChange = (oldSize, newSize) => {
// Start a process as soon as there is at least one listener
// Stop a process if there is no listener
};
function receiveAsynchronousResults(data, err) {
if (err) {
return onErrorEventSource.dispatch(err);
}
onDataEventSource.dispatch(data);
}
...
// Do something that periodically calls receiveAsynchronousResults()
...
// The two OneEventSourceConsumer objects ARE EXPORTED
return {
onData: onDataEventSource.consumer,
onError: onErrorEventSource.consumer
};
}
const someObj = createSomethingAsynchronous();
someObj.onData.addListener(data => processData(data));
someObj.onError.addListener(error => console.log(error));
Methods
(static) createEventSource() → {OneEventSource}
Creates an OneEventSource with an OneEventSourceConsumer object with public methods for consumers of the event, and non-public methods for the code that is the source of the events and is publishing the interface.
- Source:
Returns:
Returns an OneEventSource object
Type: OneEventSource