在AngularJS中处理多个异步调用和范围更新的最佳方法

时间:2018-02-08 05:35:25

标签: javascript java angularjs spring hibernate

我面临一个困难的情况,我必须根据UI上的各种过滤器过滤掉搜索结果。 Dashboard with multiple filters

每当我进行搜索时,都会有一个api调用,它会异步加载结果。用户可以在加载先前搜索条件的结果之前过滤任意次数。

httpService.get("getCREWRequests.do", filters.getValues()).then(function(data){
        $scope.requests=data;
});

我只是使用api的不同结果更新我的范围并在屏幕上显示它们。

但是,api调用是异步的,不同搜索条件的数据可能会在不同的时间出现。每当api调用返回时,记录可能会改变。因此,在任何时候,根据用户在任何特定时刻选择的过滤条件,都无法保证结果是否正确。

如何确保结果始终与过滤条件同步?

  1. 我无法同步加载结果,因为api调用有时会非常慢,用户必须等待几个小时才能看到结果。
  2. 由于数据库中的记录数量和其他一些业务限制,我无法一次性加载所有记录并在UI上过滤结果。
  3. 我无法改善后端的性能,因为它仍无法解决手头的问题。
  4. 请帮忙。

1 个答案:

答案 0 :(得分:1)

承诺是一种承诺。因此,它将始终被解析(解析/拒绝),并且在解析时将始终调用then()。

为了确保我的最新调用是执行,我们可以维护函数调用计数器。记录将被更改,只有在最新的呼叫时才会更改。

以下是一份工作样本:

var app = angular.module('TestApp', []);

app.controller('Ctrl', ['$scope', '$q', function($scope, $q) {
  var vm = this;
  vm.result = 0;

  vm.loadCount = 0;
  vm.countToBeDisplayed = 0;

  vm.getResult = function(localLoadCount) {
    var deferred = $q.defer();
    setTimeout(function() {
      console.info("localLoadCount: " + localLoadCount);
      console.info("vm.loadCount: " + vm.loadCount);
      deferred.resolve(localLoadCount);
    }, Math.floor(Math.random() * Math.floor(10)) * 1000);
    return deferred.promise;
  };


  vm.loadTestMultipleLoadsPromise = null;

  vm.invokeTestMultipleLoads = function() {
    vm.loadCount++;
    var localLoadCount = vm.loadCount;
    vm.loadTestMultipleLoadsPromise = vm.getResult(localLoadCount);
    vm.loadTestMultipleLoadsPromise.then(function successCallback(response) {
      // Checking if loadCount matches the localLoadCount
      if (vm.loadCount === localLoadCount) {
        vm.result = response;
      }
    });
  };


}]);
<!doctype html>
<html ng-app="TestApp">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>

<body>
  <div ng-controller="Ctrl as vm">
    Result: {{vm.result}}
    <button ng-click="vm.invokeTestMultipleLoads()">call test method</button>
  </div>
</body>

</html>

vm.getResult():方法就像你api调用。它具有随机超时,因此我们可以预期它的行为与慢速api相同。

vm.invokeTestMultipleLoads():从javascript / angualr调用此函数。它会在内部调用api。 每当调用此方法时,loadCount都会增加。请注意,仅当localCount与loadCount匹配时,我们才会更改结果。