Its amazing how cool things just keep popping up all over teh interwebz. Rich Hickey (of Clojure fame) commented once in a Clojure-conj talk, that "Not everything is awesome!" We flock like lambs around this or that technology because it is 'awesome,' and less because it may solve this or that problem.
I've been playing with Node.js recently. It's Javascript, it's server-side, and it's pretty cool. One of the bright ideas it brings to the table is that for developers coding on node, the system by design uses almost exclusively non-blocking IO. Other platforms have asynchronous IO too; but Node could be the poster child.
The big win here is that for an IO op that may take some time, the developer simply provides a callback, and execution merrily proceeds through the code, top to bottom, until the event fires and the callback is invoked. The advantage is not programming with callbacks; the advantage is speed of execution.
One potential problem is keeping everything wired up neatly. Exceptions can get messy. They propagate...where, exactly? And the control flow of a non-trivial system evokes memories of the GOTO (or perhaps COMEFROM) days.
Node packs a punch, its async IO is fast, and it brings the best of the V8 Javascript engine from Google to server-side apps. It is new, and I think it deserves a chance to grow into something robust and mature. Who knows, maybe it will make it into my toolkit sometime soon.
In the meantime, there are alternate solutions. For Ruby, there is Eventmachine. Python has a number of solutions as well. Both Ruby and Python provide abstractions (E.g. Fibers, green threads, etc.) which tuck the details under the covers, allowing the programmer to bring the language closer to the problem domain.
Different domains lend themselves to different styles, and in this glorious day of hip dynamic languages let me say that even C++, as barnacle-encrusted as any ship sailing the seas of leadership by committee has ever been, has the flexibility to express many different styles appropriate to different domains. We have added dynamic languages to the toolbox to gain flexibility, not to forfeit it.
To return to the example, Node.js may be appropriate to solve a certain kind of problem. Like Patterns, languages and frameworks must be understood in terms of the problems they solve, the forces they resolve. Otherwise we run the risk of being the one-trick pony, who can only bleat "NoSQL!" and is forced to write every kind of middleware, client app, and numerical simulation in a hacky, "Ajax-ian" style.