rather than threads. Threads
have been the de facto concurrency model since the 1960’s, but they were designed for a very different type of computing than what most developers work on today.
Threads were primarily designed to support scientific computing, ensuring that all researchers got to run their computations without blocking each other. Professor Smith could run his planetary motion simulator at the same time as Professor Jones was testing out his red-black tree implementation. The key problem was that these programs both required the CPU at all times in order to do computations, so the operating system needed to have two “threads” of execution to ensure that both programs got to access the CPU.
Fast forward to 2020, and most web developers barely use the CPU at all. Say you have a Node.js script that makes an HTTP request to a remote server. Node.js uses a little CPU time to serialize the request, and then spends a lot more time waiting for the response. CPU is no longer a scarce resource because most web apps do minimal computation - they defer the work across the network to some other machine.
The event loop is a much better model for programs that are network constrained rather than CPU constrained. Instead of worrying about how many threads you need and how to ensure that your threads don’t waste resources when they’re waiting for an HTTP response, you just use await
Naturally, other languages have libraries for event loops. Tornado
is a common event loop based HTTP server for Python. C# has a built-in event loop framework
as well. But those come with caveats - not all Python or C# libraries work well with event loops.