The underlying pattern and concept is called a continuation. If you can wrap your head around how call/cc works in scheme, it’ll go a long way to understanding what’s going on with the async stuff. As far as books for that, SICP?
This suggests you don’t fully grasp what async/await is doing. There is no blocking, there is no waiting. NodeJS, for example, can handle thousands of simultaneous connections with a single thread. Assuming, of course, that everything’s I/O bound because there’s only one thread.
Going from fire and forget to async/await is like going from goto statements to if/else, for, while, etc. The behavior is the same, but the code is much easier to deal with and far less prone to devolving into spaghetti code.