Promises make this both better and worse, in my experience. In the easy cases, all you have to do is follow the promises syntax, and you can treat it as linear code.
The problem arises when writing non happy path code, you not only have to think about the promises syntax, but about the abstraction it's creating over callbacks. Otherwise, you begin to miss corner cases, create incorrect promises, and in general write code which misbehaves (often silently).
Promises are powerful abstractions, but like all abstractions, they have their leaks. Also like all other abstractions, there are places where you have to fully comprehend the mechanisms underneath them to use them properly.