You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

页面偶发数据库数据未加载:寻求替代超时的技术方案

解决页面刷新时偶尔无法获取数据的问题(替代超时方案)

你的问题本质是异步执行时序不匹配——页面有时会在数据请求完成前就完成渲染,而之前用固定101ms超时的方式属于"暴力等待",完全依赖运气,一旦其他功能的执行时序和这个超时冲突,就会导致功能失效。咱们从根源重构代码,用更可靠的方式解决:

第一步:重构数据请求函数,用Promise替代回调

Angular的$http本身就返回Promise,完全没必要用回调模式,改用Promise链式调用能更精准地控制异步流程:

get_data: function (kpi, date_from, date_to) {
  var config = {
    method: 'POST',
    url: '/getData',
    data: {
      kpi: kpi,
      date_from: date_from,
      date_to: date_to
    }
  };
  // 直接返回$http的Promise,让上层通过then/catch处理结果
  return $http(config)
    .then(function (response) {
      return response.data; // 成功时返回数据
    })
    .catch(function (error) {
      console.log(error.data, error.status, error.headers, error.config);
      throw error; // 抛出错误,让上层感知请求失败
    });
}

第二步:移除外层$timeout,用Promise链式调用控制渲染时序

原来的外层$timeout是导致其他功能失效的核心——它强制延迟了整个数据请求的发起,打乱了依赖这个函数的其他操作时序。现在我们改为等数据真正返回后再处理页面逻辑:

$scope.update_all_data = function() {
  $scope.show_loading = true;
  $scope.display_nodata = false; // 先默认隐藏无数据提示

  var date_from = findDateUnix($scope.myDateFrom, $scope.availableDates);
  var date_to = findDateUnix($scope.myDateTo, $scope.availableDates);

  // 用Promise的then等待数据返回,确保数据到位后再更新视图
  UpdateSvc.get_data($scope.kpi_selected, date_from, date_to)
    .then(function(res) {
      raw_data = [];
      skey_data = [];

      if(res.raw_data != null && res.raw_data.length > 0){
        raw_data = res.raw_data;
        skey_data = res.skey_data || [];
        
        var num = $scope.show_tab.indexOf(true);
        $scope.filtering = generateCategories();
        
        // 这里的$timeout仅用于等待DOM更新后执行resizeObjects(如果需要的话)
        $timeout(function(){
          $('.md-datepicker-input').prop('disabled', true);
          resizeObjects();
          $scope.show_loading = false;
        });
      } else {
        $scope.display_nodata = true;
        $scope.show_loading = false;
      }
    })
    .catch(function() {
      // 请求失败时也要关闭loading,避免页面一直处于加载状态
      $scope.display_nodata = true;
      $scope.show_loading = false;
    });
};

为什么这个方案更可靠?

  • 精准的异步控制:不再依赖固定时间的"盲等",而是真正等待数据请求完成后再处理页面,从根源解决"页面先加载、数据未到位"的问题。
  • 避免功能冲突:移除外层$timeout后,update_all_data会立即执行,不会延迟其他依赖该函数的操作,解决之前"大量功能失效"的问题。
  • 完善的错误处理:通过catch统一处理请求失败的场景,确保loading状态一定会被关闭,避免页面卡死。

额外优化建议

  • 代码里的raw_data和skey_data看起来像全局变量,建议改成$scope绑定变量或封装到服务中,避免全局变量污染。
  • 操作DOM的$('.md-datepicker-input').prop('disabled', true)可以用Angular的ng-disabled指令替代(比如在$scope上设datepickerDisabled变量,模板中用ng-disabled="datepickerDisabled"),更符合Angular数据驱动的理念。

内容的提问来源于stack exchange,提问作者Oliver James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:00:22