Angularjs 我应该如何处理生存期大于其调用范围的http请求?

Angularjs 我应该如何处理生存期大于其调用范围的http请求?,angularjs,Angularjs,因此,我的一个$angular作用域在用户交互时启动一个$http请求。该请求需要相当长的时间才能运行,而且当其承诺得到解决时,用于启动该请求的范围可能已经消失 现在,很明显,因为js是一种很好的语言,所以scope对象仍然存在,因为它被捕获在promise处理程序变量scope中,所以,最坏的情况是,我将更新scope变量,即使scope完全未使用。但是,此处理程序中可能发生的情况之一是: $state.go("^"); 现在,如果与此作用域关联的ui路由器状态仍然处于活动状态,这将正常工作

因此,我的一个$angular作用域在用户交互时启动一个$http请求。该请求需要相当长的时间才能运行,而且当其承诺得到解决时,用于启动该请求的范围可能已经消失

现在,很明显,因为js是一种很好的语言,所以scope对象仍然存在,因为它被捕获在promise处理程序变量scope中,所以,最坏的情况是,我将更新scope变量,即使scope完全未使用。但是,此处理程序中可能发生的情况之一是:

$state.go("^");
现在,如果与此作用域关联的ui路由器状态仍然处于活动状态,这将正常工作,但当用户感到厌烦时,他们倾向于点击并返回到另一个状态,在该状态下执行$state.go(“^”)不是一个好主意

我可以:

  • 在承诺处理程序中,检查当前状态在.go(“^”)之前是否仍然是“相同的”(我将跳过“相同”的真正含义)
  • 无论如何,确保$http请求处理程序在$scope被销毁时被取消
  • 很清楚,1。是吓人的。2.还不够痛苦:

    $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就是我想的,看起来没有明显的“更好”方式。