我遵循了此处发送的出色建议(使用 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'];