我只是让我的脚湿润了Angularjs。我有一个我认为与承诺有关的问题。
假设我加载路由’A’,通过它的控制器使多个ajax请求:
allSites = AllSites.query({ id:categoryID }); allSites.$promise.then(function(allSites){ //add stuff to the scope and does other things //(including making another ajax request) });
然后我有路由’B’,它通过它的控制器使自己的API请求:
$scope.categories = Category.query();
以下是路线’A’目前使用的工厂服务:
.factory('AllSites',function($resource){ return $resource('api/categorySites/:id'); });
当我第一次查看路线“A”,但在“A”完成加载之前切换到“B”,路由“B”就坐在等待“A”中最初请求的所有内容完成(实际上是查询()请求,但是直到“A”的一个内容才会解决,在那里,内部的内容会继续发生,尽管我不需要它,因为我现在正在另一条路线上。
正如你在devtools时间线中看到的那样,绿线表示何时切换到路由’B’。直到上述两个请求(请求通常非常快),路由“B”的请求才解决。 (此时我可以将用户视为用户)。那么在此之后,更多的承诺将从路线“A”中解决。
我搜索到无处不在的答案,只能找到想要“延迟”路由加载的人,直到承诺得到解决。但在我的情况下,我几乎想要相反。当我切换时,我想杀死这些请求。
这里有一个与之相同的未解答的问题:Reject Angularjs resource promises
任何帮助是赞赏。
首先,我决定我需要使用$ http,因为我找不到使用$资源的任何解决方案,也不能让它自己工作。
所以这里是我工厂变成的,基于@ Sid的答案,使用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 }); });
然后,在我的控制器(路由’A’从我的问题):
var allSitesPromise = AllSites.getSites(categoryID); $scope.$on('$destroy',function(){ allSitesPromise.abort(); }); allSitesPromise.then(function(allSites){ // do stuff here with the result }
我希望工厂不是那么乱,但我会拿我能得到的。然而,现在有一个单独的相关问题Here,尽管承诺被取消,但下一步行动仍然延迟。如果你有一个答案,你可以在那里张贴。