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

cai*_*lin 20 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;
        })
    }
Run Code Online (Sandbox Code Playgroud)

我试过的一个解决方案:

// 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;
        })
    }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,即使我在$ 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;
        })
    }
Run Code Online (Sandbox Code Playgroud)

632*_*324 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;
    })
}
Run Code Online (Sandbox Code Playgroud)

不要忘记注入$q您的控制器/指令/服务.

  • 我找到了解决方案:我必须为每个搜索请求创建一个新的取消器,否则它总是会失败. (2认同)

cai*_*lin 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;
    })
}
Run Code Online (Sandbox Code Playgroud)