Отмена текущих запросов Angular $http при наличии нового запроса
Как отменить текущий запрос 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;
})
}
В этом сценарии, хотя я вызываю canceler.resolve перед запросом $http, запрос появляется как "сбой".
Любые идеи?
изменить: решение найдено!
// 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;
})
}
Ответы
Ответ 1
При запуске нового поиска вызовите функцию 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
в свой контроллер/директиву/службу.
Ответ 2
Решение состоит в том, чтобы установить обещание, затем с каждым поиском() отменить его и повторно инициализировать новый. Это будет надежно отменять любые предыдущие $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;
})
}