Search code examples
javascriptangularjsionic-frameworkpromisecancellation

$interval does not cancel promise right away


I have a service where I exchange data, in this service I keep a promise created by $interval, nothing fancy:

$rootScope.recursivePosition = null;
$rootScope.trackMe = function(){
    var extensionName = $state.current.extensionName;
    if ($rootScope.tracking === false) {
        $rootScope.tracking = true;

        $rootScope.recursivePosition = $interval(function(){
            someService.getAllPositions($rootScope.content[extensionName]);
        }, 2000);
    } else {
        $interval.cancel($rootScope.recursivePosition);
        console.log("recursivePosition cancel");
        console.dir($rootScope.recursivePosition);
        $rootScope.tracking = false;
    }

};

The thing is, inside that service I have another promise (from $cordovaGeolocation) when I cancel the first promise ($rootScope.recursivePosition) it still works for a while, like 4 seconds more. Can I control this behavior ?


Solution

  • A promise inside a promise can't be cancelled. But a promise derived from that promise can be cancelled.

    function getAllPositions(x) {
        var defer = $q.defer();
        var derivedPromise = defer.promise;
    
        derivedPromise.cancel = function () {
            defer.reject('cancelled');
        });
    
        $cordovaGeolocation(x)
          .then(function onSuccess(value) {
              defer.resolve(value);
        }).catch(function onReject(error) {
              defer.reject(error);
        });
    
        return derivedPromise;
    };
    

    The above example returns a promise derived from the $cordovaGeolocation promise. Attached to it is a method named cancel which rejects the promise if called before $cordovaGeolocation resolves.

    Asynchronous operations started by $cordovaGeolocation can't be stopped but operations chained from its promise can be cancelled.