I don't use Node, but my understanding is as follows:
Rather than blocking the thread on IO, you instead arrange for a callback to be executed once your IO operation is completed. The thread is then free to work on other tasks (e.g. other requests) while that operation is in progress. As a result, the thread is always busy.
The main disadvantages of this are that you are switching from straightforward top-down code to a continuation-passing style (mitigated somewhat by promises and async functions), and the fact that CPU-bound code will prevent other tasks from being serviced during execution.
There are similar facilities available in most languages now (including syntax sugar to help with things, such as C# through the async feature, and F# through the async computational expression), except that you also have the benefit of multiple threads.
Rather than blocking the thread on IO, you instead arrange for a callback to be executed once your IO operation is completed. The thread is then free to work on other tasks (e.g. other requests) while that operation is in progress. As a result, the thread is always busy.
The main disadvantages of this are that you are switching from straightforward top-down code to a continuation-passing style (mitigated somewhat by promises and async functions), and the fact that CPU-bound code will prevent other tasks from being serviced during execution.
There are similar facilities available in most languages now (including syntax sugar to help with things, such as C# through the async feature, and F# through the async computational expression), except that you also have the benefit of multiple threads.