取消由ng-change创建的先前api请求

时间:2016-02-24 04:58:44

标签: javascript angularjs

我在角度控制器中附加了一个搜索框来调用web服务来获取人员列表:

        <div class="input-group">
            <div class="input-group-addon">Find Person</div>
            <input type="text" class="form-control" placeholder="Search" ng-change="vm.getPeople()" ng-model="vm.searchTxt" ng-model-options="{debounce: 500}"/>
        </div>
它有一个辩论,不会发出太多的电话。

该功能如下所示:

    function getPeople() {

        vm.spinner = true;

        peopleClient
            .get({
                GenSearchTerm: vm.searchTxt
            })
            .success(function (data) {
                vm.spinner = false;
                vm.searchResult = data.results;
            })
            .error(function (err) {
                vm.spinner = false;
                log.debug(err);
                err;
            });
    }

这可以按预期工作,但有问题。如果我输入一个非常松散的术语,返回很多结果,那么一个非常具体的术语会返回1个结果(即&#39; a&#39;然后&#39;然后&#39; Angela Smith&#39;)数据将会返回对于特定术语首先,然后在为一般术语执行回调时更换(这是第一次但在服务器端需要更长时间。是的,服务器端调用太慢而且我会考虑在那里修复它,但是我还希望更好地处理客户端。

那么,如果我知道稍后的调用会取代它们,我怎么能停止/取消这个函数创建的任何正在进行的请求?

修改:

太棒了,这让我有了一个很好的观点,并且有很多使用超时的例子。想知道是否有人能告诉我这个简单的添加是否有问题。它在功能上有效,但不确定我是否能很好地处理承诺。

function getPeople() {

    vm.spinner = true;


    //check for existing 
    if (vm.searchPromise) {
        //cancel the existing call 
        vm.searchPromise.resolve(); 
    }
    vm.searchPromise = $q.defer();

    peopleClient
        .get({
            GenSearchTerm: vm.searchTxt
        }, vm.searchPromise)
        .success(function (data) {
            vm.spinner = false;
            vm.searchResult = data.results;
        })
        .error(function (err) {
            vm.spinner = false;
            log.debug(err);
            err;
        });

}

然后在peopleClient中:

    function get(params, deferred) {
        return $http.get(url + 'people', {
            headers: {
                Authorization: 'Bearer ' + access_token
            },
            params: params,
            timeout: deferred.promise
        });
    }

2 个答案:

答案 0 :(得分:1)

如果您使用的是restangular,则可以使用timeout : requestCancelDeferred

var requestCancelDeferred = $q.defer();

然后当您需要取消请求时:

requestCancelDeferred.resolve();

您的查询:

return Restangular
    .one('homes')
    .withHttpConfig({ timeout : requestCancelDeferred.promise })
    .get(/*your query here*/);

或使用$ http(版本1.1.5 +):

var requestCancelDeferred = $q.defer();
$http.get('/someUrl', {timeout: requestCancelDeferred.promise}).success(successCallback);

当您需要取消时:

requestCancelDeferred.resolve();

答案 1 :(得分:1)

如果您正在使用带有$ resource请求的服务工厂,您可以执行以下操作:

app.factory("peopleClient", function($http, $q) {
    var canceller = $q.defer();
    return $resource(url, options || {}, {
        'get': {
            method: 'GET',
            timeout: canceller.promise
        }
    });
});