But until the Node community can agree on a standard for this, library writers can't make their APIs dependent on these techniques, so we're stuck at the lowest-common-denominator.
And even if everybody was using Q, it's still an awful lot of boilerplate compared to saying the same thing in a language with coroutines.
And there are painful design choices that make it unlikely everyone will ever agree on a promise library. For example: Q guarantees that promises will resolve on a different stack than where they were created. This is nice, it helps you reason about the code. But there are places where you absolutely need to resolve a promise on the same stack (Node's IO handlers, or parts of the window.openDatabase API), and dealing with the edge cases is really gross.
Library authors won't, and I would argue shouldn't, make their code dependent on a particular promises implementation. When/if either ES standards body or Node authors choose a method that will become the default. Until then individuals will use the library they like, or none at all, and we've gotten by without promises in the last 10 years that JS has exploded in popularity.
By the way, Q can easily wrap node-style callbacks in a single line.
But until the Node community can agree on a standard for this, library writers can't make their APIs dependent on these techniques, so we're stuck at the lowest-common-denominator.
And even if everybody was using Q, it's still an awful lot of boilerplate compared to saying the same thing in a language with coroutines.
And there are painful design choices that make it unlikely everyone will ever agree on a promise library. For example: Q guarantees that promises will resolve on a different stack than where they were created. This is nice, it helps you reason about the code. But there are places where you absolutely need to resolve a promise on the same stack (Node's IO handlers, or parts of the window.openDatabase API), and dealing with the edge cases is really gross.