Как уничтожить неразрешенные обещания
Посмотрите на фрагмент кода
$scope.getSongs = function(keyword){
songServices.getSongList(keyword).then(
function(resp){
$scope.songList = resp.data.songList;
}
);
}
Здесь getSongList просто возвращает список песен с сервера по HTTP-запросу.
И в моем HTML:
<input auto-focus type="text" placeholder="Enter song ID/Keyword" ng-model="keyword" ng-change="getSongs()">
Проблема здесь в поведении promises, иногда, если какое-то обещание занимает больше времени (даже в ms.), чтобы получить разрешение, то оно показывает ложные данные. когда вы ищете "AKON", можно сказать, что обещание с первым ударом "A" возвращается последним, а затем обновляет область с помощью ложных данных. Есть ли способ остановить или отменить обещание, которое не было разрешено, прежде чем отправлять другое обещание серверу или как могу ли я обработать такой сценарий.
Спасибо заранее.
Ответы
Ответ 1
$http-звонки могут быть отменены, передав обещание в опции конфигурации "timeout" и разрешив это обещание.
Из документация:
timeout - {number | Promise} - тайм-аут в миллисекундах или обещание, которое должно прервать запрос при его разрешении.
Пример:
var canceler = $q.defer();
$http.get(someUrl, { timeout: canceler.promise });
// later: cancel the http request
canceler.resolve();
Ответ 2
Вместо того, чтобы уничтожить обещание, лучше не звонить, пока пользователь не перестанет печатать. вы можете использовать директиву ng-options для установки таймера отладки. Таким образом, действие будет выполнено только после того, как пользователь перестанет печатать.
<input auto-focus type="text" placeholder="Enter song ID/Keyword" ng-model="keyword" ng-change="getSongs" ng-model-options="{ debounce: 500}">
Ответ 3
Вы могли бы создать разрушаемое обещание из обычного обещания достаточно легко:
var destroyablePromise = function(p) {
var r = $q.defer();
p.then(function(a) { if (p) { r.resolve(a); }},
function(a) { if (p) { r.reject(a); }},
function(a) { if (p) { r.notify(a); }});
r.promise.destroy = function() {
p = null;
};
return r.promise;
}
Et voilà!