There must have been man-years of discussion on the Bluebird project around cancellation, but for me it all comes back to tokens as every promise baked-in solution feels a bit off. Golang effectively has them as well via the context package.
*As you say it is pretty easy to do, but it's nice to standardize on an implementation
We've had 4 cancellation proposals rejected so far (cancellation as rejection, third state, cancellable-promise and cancel-tokens).
They work in bluebird pretty well - but people have concerns.
Personally I use our cancellation if I already have bluebird, and tokens if I don't.
Basically, you can make it work pretty easily with promises and multicast (by reference counting).
The reason they're not added to promises is because some people feel they break a guarantee a promise makes. Not only is it possible - it works well.
Domenic is worn out from having to put up with all the involved shit (if you're reading this, sorry :D). He put a lot of work but I think he's tired of fighting for this rather than push other areas where he meets less resistance in the DOM.
I just wanted to point out that while cancellation is a whole world of complexity and is very interesting - it's not avoided in the language because we're stuck on the technical side.
Multicast cancelation based on refcounting doesn't look right to me. I explicitly avoided this in Posterus, sticking with exclusive ownership, what GTOR calls unicast (thanks for linking). The reason is that subscribers may come and go over time. I've seen, and written, code that caches a promise and reuses it many times. It may start with one consumer, lose it, be canceled, then another consumer comes and gets rejected. This just feels like a big footgun. In Posterus, multicast is explicit and opt-in (`.weak()` futures).
If we eventually standardise a solution, I'd like something with as few interfaces as possible. In a dynamic language, you don't have the luxury of creating a future that initialises into a task, returning a cancelation token. Too many types without static checking is just a footgun. This is part of why Posterus only has futures, why cancelation is provided in the future constructor and tied to the future itself, and why they're eager rather than lazy. Deviating from these constraints would introduce new types, increasing the footgun potential.