javascript - 如何在连续 2 个 Angular 服务调用期间中止/取消第一次调用的 promise ?

标签 javascript angularjs

当通过 $http Angular 服务对下拉项选择进行 2 个连续的服务调用时,假设第一个调用需要时间返回,第二个调用在第一个调用解析之前返回,那么它会显示第二个项目选择的第一次调用的数据。

如果在第一次调用解决之前再次进行服务调用,是否有任何方法可以中止第一个 promise 。

出于演示目的,我创建了示例 plunkar它的下拉菜单中包含几个项目,我添加了明确的条件,在选择第一个项目时,它比其他项目花费的时间更长。 因此,选择第一项并立即选择第二项来重现场景,检查屏幕上显示的最喜欢的书籍。

感谢任何帮助!

服务代码:

app.factory('bookService', function($http, $q, $timeout) {
  return {
    getBook: function(id) {
      var promise = $q.defer();
      var timeoutSpan = id == 1 ? 3000 : 500;
      $http.get("favouriteBooks.json").success(function(data) {
        $timeout(function() {
          promise.resolve(data.filter(function(obj) {
            return obj.id == id
          }));
        }, timeoutSpan);
      }).error(function(msg) {
        promise.reject(msg);
      })
      return promise.promise;
    }
  }
});

最佳答案

我找到了两种方法来处理这种情况 -

情况 1: 在服务级别创建全局 $q defer 对象,并在调用 $http 请求之前检查该对象是否有值(value)。如果此延迟对象具有值,则显式解析它。普伦卡代码 - code snippet

服务代码:

app.factory('bookService', function($http, $q, $timeout, bookConstants) {
  var service = {};
  service.mypromise = null;

  service.getBook = function(id) {
    if (service.mypromise) {
      service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
      service.mypromise = null;
    }
    service.mypromise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        if (service.mypromise) {
          service.mypromise.resolve(data.filter(function(obj) {
            service.mypromise = null;
            return obj.id == id
          }))
        }
      }, timeoutSpan);
    }).error(function(msg) {
      service.mypromise.reject(msg);
    })
    return service.mypromise.promise;
  }

  return service;

});

情况 2: 返回 $q defer 对象作为服务响应并在 Controller 级别维护它。如果是连续的服务调用,请首先检查并明确解决第一个服务调用,然后继续处理其他服务调用。 普伦卡代码 - code snippet

示例代码:

$scope.getSelectedValue = function() {
    var id = $scope.selitem.id
    $scope.cancel();
    var bookPromise = bookService.getBook(id);
    $scope.requests.push(bookPromise);
    bookPromise.promise.then(getBookSuccess)
      .catch(errorCallback)
      .finally(getBookComplete);
  }

  function getBookSuccess(favouriteBooks) {
    if (favouriteBooks == 'User Cancelled') {
      return;
    }

    var books = '';
    angular.forEach(favouriteBooks, function(book) {
      books += book.bookName + ' '
    });

    $scope.selectedvalues = 'Name: ' + $scope.selitem.name +
      ' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
  }

  function errorCallback(errorMsg) {
    console.log('Error Message: ' + errorMsg);
  }

  function getBookComplete() {
    console.log('getBook Has Completed!');
  }

  $scope.cancel = function() {
    if ($scope.requests) {
      angular.forEach($scope.requests, function(request) {
        request.resolve('User Cancelled');
        clearRequest(request);
      })
    }
  };

  var clearRequest = function(request) {
    $scope.requests.splice($scope.requests.indexOf(request), 1);
  };

}]);

app.factory('bookService', function($http, $q, $timeout) {
  var service = {};
  service.getBook = function(id) {
    var promise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        promise.resolve(data.filter(function(obj) {
          return obj.id == id
        }))
      }, timeoutSpan);
    }).error(function(msg) {
      promise.reject(msg);
    })
    return promise;
  }
  return service;
});

关于javascript - 如何在连续 2 个 Angular 服务调用期间中止/取消第一次调用的 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36708581/

相关文章:

php - JSON 返回数组的奇怪结果

javascript - 无法将参数传递给 Angular Directive(指令)

javascript - 在 Angular.js 中对 Controller 进行单元测试

angularjs - ng-repeat 中的表达式如何工作?

c# - 访问由 JavaScript 编辑的隐藏输入值

javascript - YouTube videoId从输入API获取

javascript - Vue 包装器组件无法与 axios 正常工作

javascript - promise 取消方法。为什么与其他 Promise 框架相比它还没有实现?

javascript - AngularJs 将选项附加到选择框

javascript - Protractor 找不到任何元素,但元素在浏览器中呈现