This is slightly off topic, but if we're talking about language capabilities for async:
Something I only figured out fairly recently but that shocked me is that Haskell, with its lazy evaluation, you can essentially get asynchronous programs for free, and still write in a synchronous style.
While by default the IO monad is strict (basically makes IO stuff synchronous), there are some non-strict actions that are really easy to use.
Imagine the following program:
Open two ports, and print the first couple of bytes recieved from each port.
In node (at least from the callback-based stuff), at one point you're going to have an inevitable :
while(!done){} //waiting
in Haskell, this program looks roughly like:
main = do
socket
Lazy IO in Haskell is what I call blocking on data-dependencies: because of how lazy evaluation works, Haskell is able to keep on going until the very moment you need the result from some async call.
It's even crazier that Haskell has the holy grail of async programming : the function that transforms a synchronous function to an asynchronous one.
Instead of having
main = do
x
you simply do
main = do
x
a becomes asynchronous , and nothing else in your code has to change.
(from what I understand unsafeInterleaveIO is called like that because it makes the order of your IO actions a bit uncertain, which is a problem for print statements, but when you're doing async programming this is already the case!)
Laziness makes Haskell crazy neat, and I would really love for lazy features to enter other languages. There are some issues (error handling mainly) but it gives you the best of both worlds, I find.
( I am by no means a Haskell expert, so all this might be wrong, but in my experience things work this way-ish)