The problem with event loops
There are a number of surface reasons why programming in an event loop paradigm is a pain in the ass; anyone who has ever done it can probably reel off a litany of complaints for you. I maintain, however, that many come down to a single fundamental issue. In a nutshell, event loops make you manage execution context manually, by yourself.
As I mentioned in my entry on event loops versus threads, both event loops and threads are switching contexts back and forth; it's just that threads do it all for you and in event loops you do it explicitly. Well, with that explicit context switching comes the need to explicitly manage those contexts, maintaining their state by hand. Much of the extra pain of event loops is ultimately from the various pains of doing manual context management.
(My entry on the real problem with asynchronous IO talks a bit about why manual context management is a pain. Asynchronous IO itself is obviously very closely related to event loops.)
The corollary to this is that the simpler and more regular your contexts are, the less of a pain they're going to be to manage. I think that this goes a fair way to explain the popularity of event loops for problems like serving static resources, as these problems generally have low state. Conversely the worst hell is things with irregular and constantly mutating state, especially complex state; this is the kind of thing where you vanish into a black hole of nested callback closures.
(I have a theory that this also explains why operating system programmers are often much more enamoured of event loops and state machines than regular programmers are; OS programmers are already thinking more or less explicitly about the context that their code runs in, because they always have to bear it in mind.)