AngularJS正在对服务器进行轮询,已取消



我遵循了这里发送的优秀建议(使用AngularJS进行服务器轮询),但[认为我]有时需要取消轮询,以便稍后恢复。

具体来说,我有一个数据列表。客户端每5秒轮询一次服务器,时间戳为"最后一次同步",即它授予服务器的最后一次时间。服务器以自该时间戳以来的任何更改作为响应。

有时客户端可能会自己进行更改,向服务器发送PUT。

我认为PUT请求有问题,干扰了轮询(反之亦然),导致数据不同步。我想通过取消轮询来测试这一点,直到PUT请求获得批准。。但我只是无法到达一个轮询函数每次都能成功调用自己的地方;发布可撤销的承诺;并在取消后从外部重新启动。

我有点接近一项服务("pulseService"),但我不能一直做到。它看起来像这样,但由于"无法读取未定义的属性‘poller’"而失败:

myModule.factory('pulseService', function($http, $rootScope, $timeout) {
  $rootScope.pulsePromise = null;
  var obj = {
    poller: function() {
      var thing = this;
      console.log("Here I am!");
      var semaphore = new Date().getTime();
      var query = {"timestamp": {'$gt': semaphore}};
      query = JSON.stringify(query);
      $http({method: 'GET', url: '/registrants', data: query}).
        success(function(data, status, headers, config) {
          $rootScope.error = false;
          $rootScope.$broadcast('pollFinished', data);
          $rootScope.pulsePromise = $timeout(thing.poller, 5000);
        }).
        error(function(data, status, headers, config) {
          $rootScope.error = true;
          semaphore = new Date().getTime();
          $rootScope.pulsePromise = $timeout(thing.startPolling, 15000);
        });
    }(),
    startPolling: function() {
      console.log(this);
      this.poller;
    }
  };
  return obj;
});

应要求,这是我的控制器的简化版本。。它可能有一点小麻烦,但我试图简化它:

function regCtrl($scope, $http, $rootScope, $timeout, pulseService) {
  // ...
  // Doing stuff to initialize and gather data into $scope.attendees
  $scope.$on( 'pollFinished', function( event, data ) {
    var found = false;
    angular.forEach(data, function(resultVal, resultKey) {
      while (found === false) {
        angular.forEach($scope.attendees, function(attendeeVal, attendeeKey) {
          if (attendeeVal.id == resultVal.id) {
            $scope.attendees[attendeeKey] = resultVal;
            found = true;
          }
        });
      }
      found = false;
    });
  });
  // .. Logic for pushing a change to the server
  // .....
    $timeout.cancel($rootScope.pulsePromise);
    $http({method: 'PUT', url: '/registrants/'+attendee.id, data: query }).
      success(function(data, status, headers, config) {
        attendee.isHere = data.isHere;
        console.log("rerunning");
      }).
      error(function(data, status, headers, config) {
        $scope.error = true;
      });
  // ...
  var semaphore = new Date().getTime();
  // Kickoff the polling process
  pulseService.startPolling();
}
regCtrl.$inject = ['$scope','$http','$rootScope','$timeout','pulseService'];

我认为您得到的特定错误是因为,当您执行$timeout(thing.startPolling,15000)时,startPolling是未绑定的。所以startPolling内部的"this"是未定义的。

我认为您可以用$timeout(obj.poller,…)替换这两个$timeout调用,并取消startPolling。

或者,您可以像$timeout那样绑定方法(thing.poller.bind(thing),5000)。

最新更新