But what if your tasks need to talk to other systems, that may use mutexes to control concurrent access. In that case, your HTTP request handling logic will just block on those mutexes, and all is lost, since the event loop will be stuck.
Now, you could of course rewrite those 3rd-party systems to use your event-loop instead of plain mutexes, but the point is that threads are a more natural fit for multiprocessing, from a software-engineering point of view, because they allow one to compose systems more easily.
In other words, threads have been invented for a reason. Otherwise, we might as well just go back to the Windows 3.11 era, with its cooperative multitasking model.
Your calls to third party systems should be through a callback interface.. they should not be blocking inline. The event loop will continue.
There are plenty of ways you can process out of band requests... you could use a generic-pool with a size of one instance if you really need to... However, if you are really blocking access to a single client at a time, it's likely node won't be your bottleneck.
Now, you could of course rewrite those 3rd-party systems to use your event-loop instead of plain mutexes, but the point is that threads are a more natural fit for multiprocessing, from a software-engineering point of view, because they allow one to compose systems more easily.
In other words, threads have been invented for a reason. Otherwise, we might as well just go back to the Windows 3.11 era, with its cooperative multitasking model.