Signal, light-weight self dispatching object.
A Signal is essentially a mini-dispatcher specific to one event, with its own array of listeners.
To help you understand the difference between Signal and Event, here is a rough comparison.
Events:
- Rely on String
- Single dispatcher
- All listeners will receive events the same if they do not process it
- Type/Class less
- Data are passed to the listener using payload
Signals:
- Rely on Object
- Self dispatching
- Only listeners attached to the signal are call
- Listener have signature (arguments)
Event dispatching call a bench load of listeners every time an action is dispatched. Event rely on String, and in general list of constant are used to be sure the name of the event is not misspell. That's lead to a bench load of constants to maintain to be sure to not duplicate one.
As signal are object, duplicate name is not an issue.
In Event architecture, the dispatcher function is passed in the entire app.
Signal are object based, that mean they are instances. Listeners have signature to handle data, and so it easy to handle any error and fail gently and effectively. They can also be passed through the app, between stores etc.
Also, Signals can be garbage collected. Signal's listeners don't have to be remove in a single point (dispatcher) and thus avoid memory leaks.
Creating and using Signal
Here is a simple example on how to log a message using a signal.
const logSignal = new Signal();
logSignal.add( (text) => {
console.log(text);
});
logSignal.dispatch('Hello world');
// output: 'Hello World'
Then, passing logSignal
across your project is easy as it's an object.
Signal dispatch
method return a promise
dispatch
method return a promise.
const upperCaseSignal = new Signal();
upperCaseSignal.add( (text) => {
return text.toUpperCase();
});
upperCaseSignal.dispatch('text')
.then((result) => console.log(result))
.catch((e) => console.error(e));
Command can return promise
If your Command has asynchronous call, you can return a promise
function command(text) {
return new Promise((resolve) => setTimeout( ()=> resolve(text.toUpperCase()), 1000));
}
const upperCaseSignal = new Signal('uppercase');
upperCaseSignal.add(command);
upperCaseSignal.dispatch('text')
.then((result) => console.log(result);
Remove a Command
Now we know how to add Command, let's remove them. Because Commands are function and function are objects, it's easy to remove them using the remove
method on a Signal object.
function command(text) {
return text.toUpperCase;
}
const upperCaseSignal = new Signal();
upperCaseSignal.add(command);
upperCaseSignal.remove(command);
Next: Learn how to create a Store and attach signals to it. Go to Store