Как уничтожить неразрешенные обещания

Посмотрите на фрагмент кода

$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à!