How would you propose that async/await work without Promises? Even C#'s async/await uses the same concept:
https://msdn.microsoft.com/en-us/library/system.threading.ta...Pending the implementation of new language syntax, raw Promises were a practical solution for what they set out to accomplish. If you don't think they improved callback hell at all, I expect that you probably weren't using them correctly (an easy mistake to make without looking at the documentation and/or reading the wrong tutorials / blog posts).
cf.
getAsyncValue1(a =>
getAsyncValue2(a, b =>
getAsyncValue3(b, c =>
doSomething(c)
)
)
);
and
getAsyncValue1().then(a =>
getAsyncValue2(a)
).then(b =>
getAsyncValue3(b)
).then(c =>
doSomething(c)
);
Sure, async/await flattens that to zero nested callbacks, which is great, but with that off the table I'd rather deal with code flattened to one level deep (or a few, in some edge cases) than arbitrarily many. And that's just the "callback hell" improvement; don't forget what a nightmare error handling with callbacks can be — you have to handle both synchronous exceptions and error value callback parameters, you have to deal with the possibility of the asynchronous function unexpectedly calling your callback more than once, etc.