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

时间:2013-07-10 04:35:17

标签: angularjs polling deployd

我遵循了这里发送的优秀建议(Server polling with AngularJS),但[我认为]有时需要取消轮询,以后再恢复。

具体来说,我有一个数据列表。客户端每隔5秒轮询一次服务器,其时间戳为“上次同步” - 它最后一次与服务器共享。服务器响应自该时间戳以来的任何更改。

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

我认为PUT请求存在问题,干扰轮询(反之亦然),导致数据不同步。我想通过取消轮询来测试这个,直到PUT请求被批准为止。但是我无法到达轮询功能每次都可以成功调用自己的地方;发出可以取消的承诺;并在取消后重新启动。

我与服务(“pulseService”)有点关系,但我不能一路走来。它看起来像这样,但失败了“无法读取未定义的属性'轮询'”:

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;
});

根据要求,这是我的控制器的简化版本..它可能有一点kruft但我试图简化一些东西:

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'];

1 个答案:

答案 0 :(得分:1)

我认为你得到的具体错误是因为,当你执行$ timeout(thing.startPolling,15000)时,startPolling是未绑定的。所以startPolling里面的“this”是未定义的。

我认为你可以用$ timeout(obj.poller,...)替换两个$ timeout调用,并摆脱startPolling。

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