Angularjs how to cancel resource promise when switching routes

后端 未结 5 1892
孤街浪徒
孤街浪徒 2020-11-30 05:00

I\'m just getting my feet wet with Angularjs. I have an issue which I think has something to do with promises.

Let\'s say I load route \'A\' which makes several ajax

5条回答
  •  夕颜
    夕颜 (楼主)
    2020-11-30 05:26

    First of all, I decided I needed to use $http since I couldn't find any solution that used $resource, nor could I get it to work on my own.

    So here's what my factory turned into, based on @Sid's answer here, using the guide at http://www.bennadel.com/blog/2616-aborting-ajax-requests-using-http-and-angularjs.htm

    .factory('AllSites',function($http,$q){
    
        function getSites(categoryID) {
    
            // The timeout property of the http request takes a deferred value
            // that will abort the underying AJAX request if / when the deferred
            // value is resolved.
            var deferredAbort  = $q.defer();
    
            // Initiate the AJAX request.
            var request = $http({
                method: 'get',
                url: 'api/categorySites/'+categoryID,
                timeout: deferredAbort.promise
            });
    
            // Rather than returning the http-promise object, we want to pipe it
            // through another promise so that we can "unwrap" the response
            // without letting the http-transport mechansim leak out of the
            // service layer.
            var promise = request.then(
                function( response ) {
                    return( response.data );
                },
                function() {
                    return( $q.reject( 'Something went wrong' ) );
                }
            );
    
            // Now that we have the promise that we're going to return to the
            // calling context, let's augment it with the abort method. Since
            // the $http service uses a deferred value for the timeout, then
            // all we have to do here is resolve the value and AngularJS will
            // abort the underlying AJAX request.
            promise.abort = function() {
                deferredAbort.resolve();
            };
    
            // Since we're creating functions and passing them out of scope,
            // we're creating object references that may be hard to garbage
            // collect. As such, we can perform some clean-up once we know
            // that the requests has finished.
            promise.finally(
                function() {
                    promise.abort = angular.noop;
                    deferredAbort = request = promise = null;
                }
            );
    
            return( promise );
        }
    
        // Return the public API.
        return({
            getSites: getSites
        });
    
    });
    

    Then, in my controller (route 'A' from my problem):

    var allSitesPromise = AllSites.getSites(categoryID);
    
    $scope.$on('$destroy',function(){
        allSitesPromise.abort();
    });
    
    allSitesPromise.then(function(allSites){
        // do stuff here with the result
    }
    

    I wish the factory wasn't so messy, but I'll take what I can get. However, now there's a separate, related issue Here where, though the promise was cancelled, the next actions are still delayed. If you have an answer for that, you can post it there.

提交回复
热议问题