Obviously this can be a blessing or a curse depending on who's writing the code; it's not terribly hard to write yourself a spaghetti mess of chaos in JS. Callbacks lead to a mess of nested lambdas, promises are better but still a bit clunky, and trying to work within the "few core types" led to the famous "wat" video [1], so these things come in tradeoffs.
Still, I see where Crockford is coming from (at least if I understand his point correctly). My interview language of choice is JavaScript, and I rarely use anything introduced from 2015 or later (except the shorthand function syntax). I like that the core language has basically no bureaucracy, and you can focus on just writing code.
One of the things Promises solves is nesting. If you're nesting them, you're doing it wrong.
(I don't mean "never nest them"... but if you find you're nesting them, see if you can refactor to "all()" them or similar)
The hard part, of course, is threading complex flows of variables through your .then() callbacks where later Promise calls need a previous variable or three, and that's when a lot of people give up and just resort to deeper nesting. That's what async/await does the best at solving: capturing variables automatically in a simple state machine written like classic imperative code versus manually trying to thread state through callback closures and complex return types.
Believe it or not, you can actually structure things so it's "flat" looking without async/await (or even without Promises for that matter, but Promises solve other problems too).
Just because someone argues against something like async/await, doesn't mean they want the thing async/await is supposed to address.