Asynchronous programming is a big hit as it does not block other code’s execution when something is ongoing. Usually, asynchronous states can be achieved in a few ways.
1. Using threads
In multi-core machines, we can spawn different threads to do different things asynchronously. However, the process of spawning threads requires time and each thread consumes memory, which may not scale well when many jobs are needed to be done. Examples are Apache and IIS.
2. Using event loops
The jobs are executed immediately and an event loop is used to check for the execution state of each job. This structure does not involve spawning threads so the memory usage is lower and can handle many jobs easily. Examples are Nginx and node.js.
Since the rise of node.js, the event loop structure has been proven to work well even with thousands or even millions of jobs. However, in multi-core machines the event loop structure cannot uses all the power provided by the CPU as only one thread (core) is used for computation. This can be solved by combining two structures to maximize the pros of them.