Lets take a look at existing cancelable AngularJS APIs:
$timeout can be canceled via $timeout.cancel(promise). To make this possible, a $$timeoutId (source) is registered on the promise. This value is read by the $timeout.cancel(promise) function to actually call clearTimeout(...).
Unfortunately, this is not a good example for cancelable asynchronous operations with Promises.
$timeout returns a promise on which the then(onFulfilled, onRejected) function can be called. This function returns a new promise which does not have a $$timeoutId property and therefore cannot be used to call $timeout.cancel(promise).