It's not that nobody noticed that TCL had async i/o, but that it didn't have closures, which make doing async i/o (or even user interface programming) much more difficult in TCL.
In terms of this point, the lack of closures forced one to NOT write that messy garbage of code that people complain that the newbs are doing in node. I.e. it forces one to separate out the behavior from the construction and so systems (rather than off-the-cuff demos) are cleaner and easier to read and maintain.
Are you joking? It requires you to use a bunch of global variables and other auxiliary keys and data structures to keep track of the state that you would have been able to capture in closures.
Without closures, it's even harder to write reusable "components" that you can make more than one instance of. Look over that TCL code and try to figure out how it handles making more than one instance of each kind of window. It supports multi-player mode by making multiple X11 server connections, so it can have more than one instance of each kind of window, one for each X11 server connection, and some windows can have multiple instances on each server (like the edit and map windows).
I had to write a lot of boilerplate infrastructure for creating/destroying windows and handling events, to store all the state for each window in global variables and structures, keyed by the window id, linked together symbolically, so windows on different screens don't clash, and even fix some bugs in Tk itself relating to having multiple windows on different servers: http://code.google.com/p/micropolis/source/browse/trunk/micr...
To create each window it would reload a file like this each time that set up all the globals and window links and bindings like "LinkWindow $head.map $win" and "bind $win <Visibility> {[WindowLink %W.view] Visible [string compare %s FullyObscured]}". Ugly shit man! Give me closures any day:
http://code.google.com/p/micropolis/source/browse/trunk/micr...
Multi-head X11 support was not well tested in 1993, it got confused if the X11 servers had different visuals, and the TCL menu handling code had to be rewritten to keep the state in per-window structures instead of globals that made the assumption that only one menu could be popped up across all screens at once. Notice the "set screen [winfo screen $w]" and "set tk_priv(posted@$screen) $w" stuff:
http://code.google.com/p/micropolis/source/browse/trunk/micr...