在我的服务工厂中,我查找了一个大型数据集——我想持久化它,并检查它的存在,以避免再次调用它

In my service-factory I lookup up a large dataset - I want to persist it and check for its existence to avoid calling it again

本文关键字:检查 持久化 调用 存在 大型 查找 工厂 服务 我的 一个 数据集      更新时间:2023-09-26

我的服务(工厂)进行API调用并将响应数据分配给变量:

    .factory('MedicationMatchingNamesFactory', 
                ['$http', '$q', 'MedicationDisplayNamesFactory', 
                    function MedicationMatchingNamesFactory($http, $q, MedicationDisplayNamesFactory){
        return {
            getMatchingNames: function(inputValue){
                var matches = [];
                // I thought this may be set as null so I'm able to 
                // differentiate it from the below array form (when exists)
                var allNames = null;
                    MedicationDisplayNamesFactory.getDisplayNames().then(
                            function(response){
                                // this is the large dataset - now as array
                                var allNames = response.data.displayTermsList.term;
                                angular.forEach(allNames, function(value, key){
                                    if(value.indexOf( inputValue ) !== -1){
                                        matches.push(value);
                                    }
                                });
                            }
                        );

                return matches;
            }
        };
        return MedicationMatchingNamesFactory;
    }])

我使用Angular UI的"UI-select"指令来根据输入的字符串在这个大型数据集中进行搜索。

在我的控制器中:

        $scope.$on('inputStarted', function(event, value){
            if(value.length > 3){
                $scope.meds.displayNames = MedicationMatchingNamesFactory.getMatchingNames(value);
                console.log($scope.meds.displayNames);
            }
        });

现在,为了避免每次输入字符数大于3时查询API(实际上调用另一个包含对API调用的服务),我认为如果我能够检查allNamesnull(空,请调用API)还是array(跳过调用,只使用它),那将是非常好的。

我尝试将angular.forEach部分移到调用和承诺之外,但很明显,没有发生任何事情,因为它在第一次运行时还没有解决。

在执行API调用之前,是否有方法检查此allNames数据集

您可以将allNames的声明移动到服务的返回语句之外,然后在查询API之前检查它是否为null。以这种方式allNames用作内部API调用的结果的高速缓存。

另外,请注意,最好从getMatchingNames返回promise,否则您的服务总是立即返回一个空白数组,然后在内部API调用完成后填充该数组。如果您确实返回了promise,则需要更改在inputStarted事件处理程序中设置displayNames的方式:

    MedicationMatchingNamesFactory.getMatchingNames.then(function(matches) {
      $scope.meds.displayNames = matches;
    });

你的服务可能是这样的:

    .factory('MedicationMatchingNamesFactory',
      ['$http', '$q', 'MedicationDisplayNamesFactory', 
        function MedicationMatchingNamesFactory($http, $q, MedicationDisplayNamesFactory) {
          var allNames = null;
          function getMatches(inputValue, list){
            var matches = [];
            angular.forEach(list, function(value, key){
              if(value.indexOf(inputValue) !== -1){
                matches.push(value);
              }
            });
            return matches;
          }
          return {
            getMatchingNames: function(inputValue){
              var deferred = $q.defer();
              if (allNames !== null) {
                deferred.resolve(getMatches(inputValue, allNames));
              } else {
                MedicationDisplayNamesFactory.getDisplayNames().then(
                  function(response){
                    // this is the large dataset - now as array
                    allNames = response.data.displayTermsList.term;
                    deferred.resolve(getMatches(inputValue, allNames));
                  },
                  function(reason){
                    deferred.reject(reason);
                  }
                );
              }
              return deferred.promise;
            }
          };
        }])

实际上,这个问题的解决方案很简单:我只是使用了sessionStorage,在这种情况下,它似乎完全符合我的需求,因为我需要为这个会话保留大数据集,如果它在下一个会话中丢失也没关系。目标是防止多次获取,也就是说,超过必要的次数,因为在该会话期间,里面的值不太可能更改。