【问题标题】:Clearing setTimeout when $http call is in pending当 $http 调用处于挂起状态时清除 setTimeout
【发布时间】:2016-02-01 20:17:21
【问题描述】:
function getDBCounts() {
    $http.get('URL')
        .then(function (response){
            $scope.stats = response.data;
            $scope.getDBCountsTimeOut = setTimeout(getDBCounts, 5000);
         }, function () {
             $scope.getDBCountsTimeOut = setTimeout(getDBCounts, 5000);
         })
}


$scope.$on("$destroy", function () {
    clearTimeout($scope.getDBCountsTimeOut);
});

当我要去不同的控制器时,我会确保我正在取消所有超时,但问题是当 $http 调用处于挂起状态并且我同时移动到不同的控制器时(未创建超时直到我们得到响应)并且我无法取消控制器更改的超时,因为调用处于挂起状态并且我无法清除未创建的超时。

我该如何处理这种情况。这个问题的最佳解决方案是什么。

我已经这样做了,但是在错误部分我无法区分网络错误并取消了超时,因为如果是网络错误,我仍然需要调用 setTimeout。

$scope.canceler = $q.defer();
function getDBCounts() {
     $http
       .get(apiUri + '/backend/database/stats', {timeout: $scope.canceler.promise})
        .then(function (response){
              $scope.stats = response.data;
              $scope.getDBCountsTimeOut = setTimeout(getDBCounts, 5000);
          }, function (er, second) {
              $scope.getDBCountsTimeOut = setTimeout(getDBCounts, 5000);
          })
 }

$scope.$on("$destroy", function () {
   clearTimeout($scope.getDBCountsTimeOut);
    $scope.canceler.resolve();
});

对于网络错误和超时,我得到这个作为响应:

{config: Object
data: null
headers: (name)
status: 0
statusText: ""}

现在我该如何解决这个问题。 提前致谢。

【问题讨论】:

  • 您将在超时/中止时收到网络错误。
  • 使用$timeout 与AngularJS框架$q服务有更好的集成,并且有cancel方法。
  • @如果您使用的是 Visual Studio 2013 或更高版本,那么这将对您有所帮助 - visualstudiogallery.msdn.microsoft.com/…

标签: javascript angularjs http settimeout angular-promise


【解决方案1】:

这似乎是$http API 的限制。我还希望您可以从响应/错误中判断请求是否超时。

我在这里看到的唯一方法是你不取消承诺,而是在它被销毁时在范围内设置一个标志。然后,当范围已被销毁时,您根本不设置超时:

function getDBCounts() {
    $http.get('URL')
        .then(function (response){
            $scope.stats = response.data;
         })
         .finally(function() {
             if (!$scope.destroyed) {
                 $scope.getDBCountsTimeOut = setTimeout(getDBCounts, 5000);
             }
         })
}

$scope.$on("$destroy", function () {
    clearTimeout($scope.getDBCountsTimeOut);
    $scope.destroyed = true;
});

您的方法更好,并且是“正确”的方法。但是,这似乎是不可能的。

PS:如果你想做某事而不管承诺是被解决还是被拒绝,你应该使用finally(见上文)。请注意,在较旧的浏览器(以及较旧的 JS/ECMA-Script 版本)中,finally 是保留字。如果您想确保支持较旧的浏览器,请像这样调用它:

$http.get(...)["finally"](function() {
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-09
    • 2023-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-30
    • 2021-09-15
    相关资源
    最近更新 更多