当有新请求时,取消正在进行的Angular $ http请求

时间:2016-02-13 01:45:59

标签: javascript angularjs

如果有新请求,如何取消正在进行的Angular $ http请求?

我有一个Angular应用程序,其视图是在用户输入时实时更新。有时旧请求在最新请求之后完成,这意味着视图显示错误的数据。当有新的请求时,取消上一个请求的最简单的方法是什么?

使用Angular 1.5,这是值得的。

<input ng-model = "query" ng-keyup = "search()"/>
{{results | json}}

// In the controller:
    $scope.search = function(){
        $http({
            method: "GET",
            url: "/endpoint.php"
            params: {
                query: $scope.query
            }
        }).then(function(response){
            $scope.results = response.data;
        })
    }

我尝试过一种解决方案:

// In the controller:
    var canceler = $q.resolve();    // New
    $scope.search = function(){
        canceler.resolve("Canceling old request");     // New
        $http({
            method: "GET",
            url: "/endpoint.php"
            params: {
                query: $scope.query
            },
            timeout: canceler.promise    // New
        }).then(function(response){
            $scope.results = response.data;
        })
    }

在这种情况下,即使我在$ http请求之前调用了canceler.resolve,该请求也会变为“失败”。

任何见解?

编辑:找到解决方案!

// In the controller:
    var canceler = $q.defer();

    $scope.search = function(){
        canceler.resolve("cancelled"); // Resolve the previous canceler
        canceler = $q.defer();        // Important: Create a new canceler! 
                                      // Otherwise all $http requests made will fail
        $http({
            method: "GET",
            url: "/endpoint.php"
            params: {
                query: $scope.query
            }
        }).then(function(response){
            $scope.results = response.data;
        })
    }

2 个答案:

答案 0 :(得分:11)

开始新搜索时,请调用cancel()功能。并且您可以使用resolved变量来确保在启动之前不会中止$http调用。像这样:

var canceler = $q.defer();
var resolved = false;

var cancel = function() {
    canceler.resolve("http call aborted");
};

$scope.search = function() {
    if (resolved) {
        cancel();
    }

    canceler = $q.defer();
    resolved = true;

    $http({
        method: "GET",
        url: "/endpoint.php"
        params: {
            query: $scope.query
        }
        timeout: canceler.promise
    }).then(function(response) {
        $scope.results = response.data;
        resolved = false;
    })
}

不要忘记在控制器/指令/服务中注入$q

答案 1 :(得分:6)

解决方案是设置承诺,然后每次搜索()取消它并重新初始化一个新的。这将可靠地取消任何先前的$ http():

var canceler = $q.defer();

$scope.search = function() {

    canceler.resolve();

    canceler = $q.defer();

    $http({
        method: "GET",
        url: "/endpoint.php"
        params: {
            query: $scope.query
        }
        timeout: canceler.promise
    }).then(function(response) {
        $scope.results = response.data;
    })
}