I understand the idea of blocking I/O and skipping that until a function/thread returns.
I understand the idea of blocking I/O and skipping that until a function/thread returns.
Of course, many high-performance, I/O intensive applications like web-servers can effectively make use of a combination of multiple threads and I/O demultiplexing as well.
The biggest practical difference is synchronization-free programming. In other words event loops are already always synchronized and you can do whatever you want with shared memory knowing that no other code is going to interfere until you explicitly stop and give up control. This allows for more reliable and more complex concurrent applications with less effort.
You understand it better than you realize. The idea of a "thread" is that it's a sequentially run context for computation with a bunch of context carried with it (a stack, references to a heap). This sequence of computations can be pre-empted.
When OO systems offer "promises" what they're doing is essentially freeing a thread from the continuity of the computation and leveraging closures or object scope to hold the context. Instead of a thread representing the computation, now threads pick up computations and work on them until they stop for I/O, then resume them when the underlying async I/O layer has work for them.
I can tell you about it in terms of monadic computations or how it relates to other concurrency strategies if you'd like, but it will become more theory-dense rather quickly.