Angularjs 我应该如何处理生存期大于其调用范围的http请求?
因此,我的一个$angular作用域在用户交互时启动一个$http请求。该请求需要相当长的时间才能运行,而且当其承诺得到解决时,用于启动该请求的范围可能已经消失 现在,很明显,因为js是一种很好的语言,所以scope对象仍然存在,因为它被捕获在promise处理程序变量scope中,所以,最坏的情况是,我将更新scope变量,即使scope完全未使用。但是,此处理程序中可能发生的情况之一是:Angularjs 我应该如何处理生存期大于其调用范围的http请求?,angularjs,Angularjs,因此,我的一个$angular作用域在用户交互时启动一个$http请求。该请求需要相当长的时间才能运行,而且当其承诺得到解决时,用于启动该请求的范围可能已经消失 现在,很明显,因为js是一种很好的语言,所以scope对象仍然存在,因为它被捕获在promise处理程序变量scope中,所以,最坏的情况是,我将更新scope变量,即使scope完全未使用。但是,此处理程序中可能发生的情况之一是: $state.go("^"); 现在,如果与此作用域关联的ui路由器状态仍然处于活动状态,这将正常工作
$state.go("^");
现在,如果与此作用域关联的ui路由器状态仍然处于活动状态,这将正常工作,但当用户感到厌烦时,他们倾向于点击并返回到另一个状态,在该状态下执行$state.go(“^”)不是一个好主意
我可以:
$scope.running_http_request = $http.get(...).then(function (result) {...});
$scope.$on("destroy", function () {
$scope.running_http_request.cancel()
});
(是的,$http请求上没有本机cancel方法,但添加它并不可怕,所以我可以这样做)
现在,所有这些都是非常痛苦的:有没有更好的方法来确保如果我的$scope消失了,那么与该scope挂起的任何东西也会消失?也许不是最漂亮的方法,但是下面的类:
import angular from "angular";
export class HttpManager {
constructor($scope) {
let self = this;
self.pendingRequests = [];
self.nextRequestId = 0;
$scope.$on("destroy", function () {
self.pendingRequests.forEach(function (request) {
request.canceler.resolve();
});
self.requests = [];
})
}
_do(config) {
let self = this;
let injector = angular.injector(["ng"])
let $q = injector.get('$q');
let $http = injector.get('$http');
let requestId = self.nextRequestId;
self.nextRequestId++;
let canceller = $q.defer();
let cfg = angular.merge(config, { timeout: canceller.promise });
self.pendingRequests.push({
id: requestId,
canceller: canceller
});
let requestPromise = $http(cfg);
requestPromise.finally(function() {
self.pendingRequests = self.pendingRequests.filter(request => request.id === requestId);
});
return requestPromise;
}
post(url, data, config) {
return this._do(angular.merge({method: "post", url: url, data: data}, config));
}
};
可按如下方式使用:
import { HttpManager } from "utils/http-manager.js"
MyController() {
$scope.http = HttpManager($scope);
$scope.http.post(...);
}
也许这不是最漂亮的方法,但是下面的课程:
import angular from "angular";
export class HttpManager {
constructor($scope) {
let self = this;
self.pendingRequests = [];
self.nextRequestId = 0;
$scope.$on("destroy", function () {
self.pendingRequests.forEach(function (request) {
request.canceler.resolve();
});
self.requests = [];
})
}
_do(config) {
let self = this;
let injector = angular.injector(["ng"])
let $q = injector.get('$q');
let $http = injector.get('$http');
let requestId = self.nextRequestId;
self.nextRequestId++;
let canceller = $q.defer();
let cfg = angular.merge(config, { timeout: canceller.promise });
self.pendingRequests.push({
id: requestId,
canceller: canceller
});
let requestPromise = $http(cfg);
requestPromise.finally(function() {
self.pendingRequests = self.pendingRequests.filter(request => request.id === requestId);
});
return requestPromise;
}
post(url, data, config) {
return this._do(angular.merge({method: "post", url: url, data: data}, config));
}
};
可按如下方式使用:
import { HttpManager } from "utils/http-manager.js"
MyController() {
$scope.http = HttpManager($scope);
$scope.http.post(...);
}
在angular中有一种取消HTTP请求的能力,请看一看问题,我将使用第一个问题,因为它似乎更容易实现。不取消挂起的http请求通常没什么大不了的。然而,我将回顾调用
$state.go(“^”)是否是一个好主意
如果http成功,您可以编辑您的问题并输入您想要的最终目标/行为吗?你害怕请求被多次发出吗?或者你在寻找取消请求的最佳方式?@bumpy:是的,这是相关的:他们使用的httpService就是我所想的,似乎没有明显的“更好”的方式。从角度看,有一种取消HTTP请求的能力。看看问题吧,我会选择第一种方式,因为它似乎更容易实现。不取消挂起的http请求通常没什么大不了的。然而,我将回顾调用$state.go(“^”)是否是一个好主意
如果http成功,您可以编辑您的问题并输入您想要的最终目标/行为吗?你害怕请求被多次发出吗?还是你在寻找取消请求的最佳方式?@bumpy:是的,这是相关的:他们使用的httpService就是我想的,看起来没有明显的“更好”方式。