Event-Driven and Callback Programming
In event-driven programming, the application reacts to events such as user clicks, network responses, timers, device signals, or messages.
10.1 Core idea
In event-driven programming, the application reacts to events such as user clicks, network responses, timers, device signals, or messages. An event loop or framework dispatches work to registered handlers.
10.2 Event handlers
The application registers a callback; it does not need to poll the button manually. The browser controls when the handler is invoked.
button.addEventListener("click", () => {
console.log("Button clicked");
});10.3 Callbacks
A callback is a function passed to another component to be invoked later or in response to a condition.
A production implementation should also validate response data, handle cancellation, and ensure error information shown to users is safe. The callback model can become hard to follow when nested deeply.
Try it: the event loop dispatching callbacks An event-driven program registers handlers and lets an event loop call them. The visualizer below (shared with the Concurrency & Async Programming course) steps through a stated host model of the JavaScript event loop; the final output of each preset was checked against a real Node.js run.
function loadData(onSuccess, onError) {
fetch("/api/courses")
.then(response => {
if (!response.ok) throw new Error("Request failed");
return response.json();
})
.then(onSuccess)
.catch(onError);
}eventloop10.4 Event propagation and delegation
In browsers, events may travel through capture and bubble phases. Event delegation attaches a handler to a common ancestor and checks the event target. Validate target assumptions and clean up listeners to prevent memory leaks.
10.5 Event sourcing versus event-driven architecture
These are related but distinct:
Event-driven architecture: components communicate or react to events.
Event sourcing: state changes are represented as an append-only sequence of domain events from which state can be reconstructed or projected.
Event sourcing adds requirements around schema evolution, replay, idempotency, ordering, storage, and privacy/deletion.
10.6 Event-driven trade-offs
Loose temporal coupling Natural UI and integration model Components can react independently Hidden control flow Duplicate or reordered events
Difficult debugging across asynchronous boundaries Listener lifecycle and resource cleanup Need for idempotent handlers
Exercise
Build a small UI where course cards emit selection events and a details panel responds. Test repeated clicks, component removal, and failed loading.
Quiz
? In event-driven code, who decides when a click handler runs?
- The handler itself, by polling. :: Handlers do not poll.
+ The browser or framework's event loop, when the event occurs. :: The application only registers the callback.
- The CSS engine. :: CSS does not dispatch events.
- The compiler. :: Dispatch happens at runtime.
? What is the difference between event-driven architecture and event sourcing?
+ Event-driven: components react to events. Event sourcing: state is reconstructed from an append-only log of domain events. :: They are related but distinct.
- They are synonyms. :: The module explicitly separates them.
- Event sourcing means using DOM events. :: It is about storing domain events.
- Event-driven systems cannot store events. :: They can; that is not the distinction.
? Which are challenges of event-driven designs? (select all that apply)
+ Hidden control flow :: The order of execution is not visible in one place.
+ Duplicate or reordered events :: Handlers should be idempotent.
+ Listener lifecycle and cleanup :: Forgotten listeners leak memory.
- Components must be tightly coupled :: Events reduce coupling.