> Coming from Java to JavaScript, I really, really yearn for the equivalent of ThreadLocals
While I understand why you feel that way today, you may find yourself some point in the future deeply, deeply detesting ThreadLocal. Sure it seems all convenient but all hell breaks loose when you need to use a threadpool, a future, an actor model...
This a Node limitation, though. E.g. .NET has had asynchronous call contexts, which encapsulate stuff such as "async thread locals", for a very long time.
Similarly, for the stacks, it's largely a tooling issue - if the debugger understands async, and the framework retains enough information about the origin of the promise, it can re-create the original stack trace, and combine it with the current one - .NET debuggers in VS and VSCode do this, as well, and WinRT even does this for C++.
Coming from Java to JavaScript, I really, really yearn for the equivalent of ThreadLocals. For example, most Java logging libraries let you set a "context" object that can be used for logging a request ID or user ID anywhere down the call stack. You can't do that in Node, so instead you have to explicitly pass that context object down in all your function calls, or make use of brittle, complicated, hacky, not-fully-supported features like "continuation local storage".
Debugging stack traces in an async/await world is a mess because you don't get a nice "from the start of the request down to this call" view of the stack.
Perhaps most importantly, with Node at least you need to worry about starving your main event loop because there is only a single top-level main thread (but understand that's not inherent to the async/await issue in general).