An order comes in. After that a confirmation should go out, the warehouse should be told, a figure should go up and perhaps an accounting entry should appear. You can write all of that one after another into the order function. Or the order function merely announces: “an order has come in”. Whoever wants to react signs up for it.
The first is called an event, the second a listener. The advantage is that a new reaction can be added without touching the order function. The price is that reading the code no longer shows you straight away everything that happens.
Where the line runs
Decoupling is not an end in itself. We use events where several areas react independently to the same occurrence, and leave it alone where two fixed steps follow each other.
The important question is what happens when a listener fails. Should the order still stand if the confirmation email does not go out? Usually yes, but somebody has to find out about it. That is exactly why reactions like these often run through a queue, which can retry an attempt instead of dropping it quietly.