加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

数组 – 如何更有效地合并Angular应用程序中的REST调用结果

发布时间:2020-12-17 06:58:39 所属栏目:安全 来源:网络整理
导读:我在SharePoint 2013页面上运行了Angular SPA.在代码中,我使用$q从使用REST从10个不同的SharePoint列表中提取数据,然后将它们合并到一个 JSON对象中以便在网格中使用.代码运行并输出预期的合并数据,但是它会泄漏并在一段时间后崩溃浏览器. 这是服务中的代码
我在SharePoint 2013页面上运行了Angular SPA.在代码中,我使用$q从使用REST从10个不同的SharePoint列表中提取数据,然后将它们合并到一个 JSON对象中以便在网格中使用.代码运行并输出预期的合并数据,但是它会泄漏并在一段时间后崩溃浏览器.

这是服务中的代码:

factory.getGridInfo = function() { 
    var deferred = $q.defer();

    var list_1a = CRUDFactory.getListItems("ListA","column1,column2,column3");
    var list_1b = CRUDFactory.getListItems("ListB",column3");
    var list_2a = CRUDFactory.getListItems("ListC","column4");
    var list_2b = CRUDFactory.getListItems("ListD","column4");
    var list_3a = CRUDFactory.getListItems("ListE","column5");
    var list_3b = CRUDFactory.getListItems("ListF","column5");
    var list_4a = CRUDFactory.getListItems("ListG","column6");
    var list_4b = CRUDFactory.getListItems("ListH","column6");
    var list_5a = CRUDFactory.getListItems("ListI","column7");
    var list_5b = CRUDFactory.getListItems("ListJ","column7");

    $q.all([list_1a,list_1b,list_2a,list_2b,list_3a,list_3b,list_4a,list_4b,list_5a,list_5b]) 
    .then(function(results){
        var results_1a = results[0].data.d.results;
        var results_1b = results[1].data.d.results;
        var results_2a = results[2].data.d.results;
        var results_2b = results[3].data.d.results;
        var results_3a = results[4].data.d.results;
        var results_3b = results[5].data.d.results;
        var results_4a = results[6].data.d.results;
        var results_4b = results[7].data.d.results;
        var results_5a = results[8].data.d.results;
        var results_5b = results[9].data.d.results;

        var combined_1 = results_1a.concat(results_1b);
        var combined_2 = results_2a.concat(results_2b);
        var combined_3 = results_3a.concat(results_3b);
        var combined_4 = results_4a.concat(results_4b);
        var combined_5 = results_5a.concat(results_5b);

        for(var i = 0; i < combined_1.length; i++){ 
            var currObj = combined_1[i];
            currObj["column4"] = combined_2[i].column4;
            currObj["column5"] = combined_3[i].column5;
            currObj["column6"] = combined_4[i].column6;
            currObj["column7"] = combined_5[i].column7;

            factory.newObjectArray[i] = currObj;

        }
        deferred.resolve(factory.newObjectArray);
    },function (error) {
        deferred.reject(error);
    });         
    return deferred.promise;
};

这是CRUDFactory中的REST调用:

factory.getListItems = function (listName,columns){
    var webUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('"+listName+"')/items?$select="+columns+"&$top=5000";
    var options = {
        headers: { "Accept": "application/json; odata=verbose" },method: 'GET',url: webUrl                 
    };
    return $http(options);
};

然后这是控制器位:

$scope.refreshGridData = function(){ 
    $scope.hideLoadingGif = false;
    $scope.GridData = "";
    GlobalFactory.getGridInfo()
    .then(function(){
        $scope.GridData = GlobalFactory.newObjectArray;
        $scope.hideLoadingGif = true;
    });
};

更新1:每个请求,这是HTML(只是一个简单的div我们正在使用angular-ui-grid)

<div ui-grid="GridOptions" class="grid" ui-grid-selection ui-grid-exporter ui-grid-save-state></div>

此代码首先声明一些get调用,然后使用$q.all迭代调用并获取数据.然后它存储结果并将它们合并为5个总数组.然后,因为我的列表结构是正确的和静态的,我能够迭代其中一个合并的数组并将其他数组中的数据拉入一个我分配给factory.newObjectArray的主数组中,我将其声明为我的服务中的全局并用作我的网格数据源.

代码运行并没有引起任何错误,但问题是(我相信)“getGridInfo”函数.如果我没有注释掉任何REST调用,浏览器将使用45 MB的数据,这些数据不会被GC拾取,然后在每次点击时复合,直到会话结束或崩溃.如果我注释掉除了一个的所有呼叫,我的页面只使用18.4 MB的内存,这很高,但我可以忍受它.

那是什么交易?我需要在某处摧毁某些东西吗?如果是这样,又怎么样?或者这与我正在使用的REST功能有关吗?

更新2:网格使用的返回结果(factory.newObjectArray)包含总共5,450个项目,并且每个项目在合并后具有大约80个属性.上面的代码是简化的,显示了每个列表中几列的拉动,但实际上,我每个列表拉5-10列.

解决方法

在一天结束时,您正在处理大量数据,因此内存问题可能始终是一个问题,您应该考虑是否需要将所有数据都存储在内存中.

您应该尝试实现的主要目标是限制数组的重复,并尽量保持内存占用尽可能低,并在完成处理后尽快释放内存.

请考虑以下事项.您提到返回的实际列数超过您的示例,因此我考虑了这一点.

factory.getGridInfo = function () {

  var deferred = $q.defer(),// list definitions
    lists = [
      { name: 'ListA',columns: ['column1','column2','column3'] },{ name: 'ListB','column3'],combineWith: 'ListA' },{ name: 'ListC',columns: ['column4'] },{ name: 'ListD',columns: ['column4'],combineWith: 'ListC' },{ name: 'ListE',columns: ['column5'] },{ name: 'ListF',columns: ['column5'],combineWith: 'ListE' },{ name: 'ListG',columns: ['column6'] },{ name: 'ListH',columns: ['column6'],combineWith: 'ListG' },{ name: 'ListI',columns: ['column7'] },{ name: 'ListJ',columns: ['column7'],combineWith: 'ListI' },],// Combines two arrays without creating a new array,mindful of lenth limitations
    combineArrays = function (a,b) {
      var len = b.length;
      for (var i = 0; i < len; i = i + 5000) {
        a.unshift.apply(a,b.slice(i,i + 5000));
      }
    };

  $q.all(lists.map(function (list) { return CRUDFactory.getListItems(list.name,list.columns.join()); }))
  .then(function (results) {

    var listResultMap = {},var baseList = 'ListA';

    // map our results to our list names
    for(var i = 0; i < results.length; i++) {
      listResultMap[lists[i].name] = results[i].data.d.results;
    }

    // loop around our lists
    for(var i = 0; i < lists.length; i++) {
      var listName = lists[i].name,combineWith = lists[i].combineWith;
      if(combineWith) {
        combineArrays(listResultMap[combineWith],listResultMap[listName]);
        delete listResultMap[listName];
      }
    }

    // build result
    factory.newObjectArray = listResultMap[baseList].map(function(item) {
      for(var i = 0; i < lists.length; i++) {
        if(list.name !== baseList) {
          for(var c = 0; c < lists[i].columns.length; c++) {
            var columnName = lists[i].columns[c];
            item[columnName] = listResultMap[list.name][columnName];
          }
        }
      }
      return item;
    });

    // clean up our remaining results
    for (var i = 0; i < results.length; i++) {
      delete results[i].data.d.results;
      delete results[i];
    }

    deferred.resolve(factory.newObjectArray);

  },function (error) {
    deferred.reject(error);
  });
  return deferred.promise;
};

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读