2 Answers

A popular metaphor often used to describe the difference between an asynchronous, non-blocking model (eg: nodejs) and a synchronous, blocking model (eg: java) is a restaurant.

Asynchronous modelThink of a web application as a restaurant and its incoming requests as customers making orders. An asynchronous application would allow a single waiter to serve multiple customers at once. The waiter takes one table's order and brings their order ticket to the kitchen. Instead of waiting for the kitchen to complete the ticket, the waiter can wait on other tables and handle new orders. Periodically the waiter returns to the kitchen to check the status of his tickets and would serve the customers as orders are completed.

Synchronous modelA synchronous "restaurant" would dedicate a single waiter to a single customer from the start of its order to completion. As a result, the restaurant needs as many waiters as customers. Furthermore, there would be times when waiters would wait while other work could be done.

Notice there are certain tasks which take a longer amount of time, but you aren't just going to put water in a pot and watch it boil. In the meantime, you might decide to work on #4 and if you finish that fire up another stove and start #5.

There's only one of you, just like there's only one process in node.js... yet you can still multitask by starting "blocking" operations (in our cases anything involving heating) and moving onto other things while you wait for them to complete.

Node works the same way. There's one process with a single thread, but you can write code in such a way that things that take a long time (disk I/O, network I/O, etc) can be interleaved with other operations.