> also ignorant, because 1990s C was decidedly synchronous
There was definitely threading in C in the 1990's, and threads are asynchronous by nature. There's a whole class of synchronization bugs that C and C++ developers had to learn to deal with, and while JavaScript developers get to avoid some by the nature of there being a single thread, that doesn't necessarily exempt them from all of them.
Threading implementation was async, not the programming model. Async programming style/model(as far as I'm aware) refers to the use of callbacks or coroutines, neither of which was common at all in C in the 1990s.
Indeed, nginx caused big waves due to its superior IO performance as the first popular async http server released in 2004.
But correct me if you have a different understanding of the term.
Your post manages to say nothing correct. Javascript did not invent callbacks, asynchronous programming, or event driven programming. Nodejs popularized it in the 2010s but you are claiming credit for something that has been in common use since the 70s. I have no clue how anyone can speak with such authority while clearly having not done a cursory glance at programming APIs available in the 80s and 90s.
Lighttpd was released before nginx and was wildly popular for a good while. Not to mention other servers like AOLserver in the 90s.
The use of non blocking sockets was nothing new, used heavily in C code throughout the 90s and is the basis of asynchronous processing (refer to Stevens Unix network programming). You should also read documents by John Ousterhout written in the 90s about this topic.
Now just about every major GUI library was targeted in C or Pascal and used an event driven callback model. You can refer to the Windows API, the modern Mac carbon API which was developed in the 80s at Next and the older Mac SDK. The Windows SDK allows event driven programming for UI and IO.
tcl/tk. Just about anything on top of X (ie Motif, GTK). The list will go on and on.
Do some research before making bold claims about C programmers not understanding asynchronous programming and callbacks.
Also I think the other reply is correct in asserting that your definition of async is making distinctions without differences.
Eg from 1995: https://web.stanford.edu/~ouster/cgi-bin/papers/threads.pdf
Note that event driven programming was nothing new in 1995.. it was the basis for the Windows api designed years prior after all, but this was around the time that multithreading was pushed for everything.
I'm referring to Os level threads, but functionally it's no different if we talk about forking with shared memory. Given that the vast majority of computing 15 years ago was single processor and multi-process or multi-thread for ansynchronous behavior (or use of select), it's all functionally equivalent, and many of the same problems discovered many decades ago for multi-process programs apply.
If I have a main program, and I fork a child to handle a task, and use shared memory to communicate, how is that any different than Javascript executing and and async call that sets or returns a value? The Javascript runtime has the same behavior as the OS scheduler in this, and if there's a single processor, it necessarily will only execute one instruction at a time. There's still plenty of pitfalls to worry about and that's why locks were (and are) useful, and why they are included with OS thread implementations (which are really just a nice API on forks and shared memory often dealt with by the OS for additional benefit).
There was definitely threading in C in the 1990's, and threads are asynchronous by nature. There's a whole class of synchronization bugs that C and C++ developers had to learn to deal with, and while JavaScript developers get to avoid some by the nature of there being a single thread, that doesn't necessarily exempt them from all of them.