How to use the EventBus in Base
Emit an event, let listeners react, and keep the code that causes from the code that responds.
How to use the EventBus in Base
Some work in an application should not block the thing that triggered it. A user signs up, and you want to send a welcome email, warm a cache, and record an analytics event. None of those should make the signup itself slower or fail if one of them does. The EventBus is how Base lets one part of your worker announce that something happened and other parts respond, without those parts knowing about each other.
The three pieces
The EventBus has a small vocabulary.
An event is a plain object that says what happened. At its simplest it carries a name, and you extend it with whatever data describes the occurrence. An event is a fact: "a user was created," with the user attached. It does not know or care who listens.
A listener is a class that handles an event. It declares which event it cares about and what to do when that event is published. Because a listener is a class, it participates in dependency injection, so it can ask for the repository or service it needs to do its work.
The bus is what connects them. You publish an event to the bus, and the bus delivers it to every listener registered for that event. The publisher does not hold a list of listeners; it just announces. That decoupling is the whole point: the code that creates a user does not import, know about, or wait on the code that sends the welcome email.
Publish now, or publish after the response
Base gives you two timings for emitting an event, and choosing between them is the main decision you make.
Publish immediately when the work should happen as part of the current flow and you want it to run now. The bus delivers the event to its listeners in the course of handling the request.
Publish as a deferred action when the work should happen after the current request has already returned its response. This is the pattern for the welcome email and the analytics ping: the user gets their fast signup response, and the follow-on work runs afterward, off the critical path. The request does not wait on it.
That deferred option is what makes the EventBus more than a function call. It lets you keep slow or non-essential work from delaying the response, while still expressing it as a clean "when X happens, do Y" rather than as manual scheduling.
Why announce instead of call
You could skip the bus and have the signup code call the email code directly. For two things, that is fine. The reason to reach for the EventBus is the third and fourth thing, and the fifth. Every time you add a reaction to an event by wiring another direct call, the originating code grows another dependency and another way to fail. With the bus, the originating code keeps publishing the same single event, and you add or remove listeners independently. The fact that happened stays one line; the reactions to it are a list you can change without touching the thing that triggered them.
The mental model to keep
The EventBus is publish and subscribe inside your worker. Publish an event to announce a fact; listeners registered for that event react to it. Choose immediate publishing when the work belongs in the current flow, and deferred publishing when it should run after the response so the caller never waits. The publisher and the listeners never have to know about each other, which is what keeps your worker's parts loosely coupled as the reactions to an event multiply.