This is because the result of the promise chain from $interval does not have a property that contains the interval id ( $$intervalId ). In the first case, you keep the promise of the timer that has $intervalId , in the second case, you keep the promise returned from the chain, which is the raw q promise without the $intervalId property (which is a custom property added by promise, keep the corresponding setInterval id when calling $interval(... ). When you cancel the timer, it needs $intervalId to cancel the $intervalId and reject the promise of the timer.
This is what interval.cancel does
interval.cancel = function(promise) { if (promise && promise.$$intervalId in intervals) { intervals[promise.$$intervalId].reject('canceled'); clearInterval(promise.$$intervalId); delete intervals[promise.$$intervalId]; return true; } return false; };
Pay attention to the line: -
if (promise && promise.$$intervalId in intervals) {
intervals is nothing more than an intervalId card and its corresponding promise (example: - {1:promiseOfInterval1, 2:promiseOfInterval2} ), so without intervalId it is not canceled. In short, the promise returned by the $ interval is the q promise plus the $ intervalId property, and when you are focused on it, itβs just an implementation of $q that returns the promise of the deferred object.
source share