【发布时间】:2015-08-15 23:29:54
【问题描述】:
我已经看到很多关于这个主题的帖子,以及很多网络文章,但我仍然被我的问题所困扰。我发现this post 非常有用,但我的 timeoutRequest() 函数永远不会被调用。
我正在使用具有 $http 超时属性的承诺,但基础 HTTP 请求没有被取消。我认为承诺本身正在解决,但请求并未取消。
我的控制器行为如下所示:
$scope.enquiriesSelected = function() {
$scope.cancelHttpRequests();
$location.path("/enquiries");
};
$scope.cancelHttpRequests = function () {
console.log(canceller.promise.$$state);
canceller.resolve("User cancelled");
console.log(canceller.promise.$$state);
};
我的 HTTP 请求承诺如下所示:
var canceller = $q.defer();
$scope.searchResultsPromise = $http({
url: "/api/customers/customersearch",
method: "POST",
data: criteria,
timeout: canceller.promise
})
.success(function(data) {
$scope.customerSearchResults = data;
});
我已经尝试了各种方法来让它工作,包括将取消器放在 $scope 中。
我一直在查看 AngularJS 源代码,发现以下几行:
if (timeout > 0) {
var timeoutId = $browserDefer(timeoutRequest, timeout);
} else if (isPromiseLike(timeout)) {
timeout.then(timeoutRequest);
}
function timeoutRequest() {
jsonpDone && jsonpDone();
xhr && xhr.abort();
}
但是,当我的承诺得到解决时,执行路径没有到达这些行。 xhr.abort() 永远不会被调用,这是 AngularJS 源代码中唯一中止 HTTP 请求的地方。
在尝试取消请求时使用 F12 (Chrome) 中的控制台进行检查会发现,promise 的 $$state 从 0 变为 1,因此我有理由确定 promise 正在解决。然而,在网络流量中,HTTP 请求并没有被取消。在 HTTP 请求完成之前,我无法导航到另一个页面。
谁能帮忙?
M
【问题讨论】:
-
如果您的请求需要很长时间,我可能会在服务器端创建一个布尔值,表示数据已加载/准备好,如果布尔值为真,您可以每秒检查一次,取回数据。这里有两个优点:用户可以取消计时器并避免检查数据准备好,浏览器不会挂起。
-
恐怕我做不到。我正在调用一个我没有源代码的服务。
-
为什么要将 promise 保存到 $scope.searchResultsPromise ?如果你删除它,有帮助吗?
-
这里的问题理论上相当简单,但实现起来却非常复杂,想象一下客户端服务器架构。一旦客户端完成发送请求,服务器将超时该请求。因此,您必须在服务器端对其进行编码以允许以超时毫秒为值的可选参数,如果设置了该请求处理所需的时间超过超时,则服务器将发送超时错误。但即使在这种情况下,也没有考虑到通信时间的流逝。客户端设置的超时只返回错误的承诺而不处理响应
-
为了缩小这个范围,你能不能在一个完全简单的 Angular 应用程序中重新创建这个问题,只有一个控制器,只有这个 http 请求被触发,然后发布代码 + 一个链接到它工作(/不工作)某处?
标签: javascript angularjs