I'm all for using coroutines to solve this problem. That's the approach taken by my Celluloid::IO library:
Unfortunately Ryan Dahl is adamantly opposed to coroutines so that's not going to happen in Node any time soon.
What would make Node more attractive is if it supported copy-on-write multithreading and gave me a way to cheat and use asynchronous I/O (like a wait(myFunctionThatTakesACallbackOrDeferred) function)
Note: I still think this approach sucks.
V8 provides a really awesome shared-nothing multithreading scheme via web workers. It's just nobody uses them.
See Tim's thread, My Humble Coroutine Proposal (https://groups.google.com/forum/#!topic/nodejs/HJOyNMKLgB8). Warning: long.
Until then, NodeJS is almost certainly the most tasteful solution to the most common problems. I hope its replacement meets so high a standard.