首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用AngularJS的服务器轮询

使用AngularJS的服务器轮询
EN

Stack Overflow用户
提问于 2012-12-03 00:07:03
回答 3查看 70.7K关注 0票数 86

我正在努力学习AngularJS。我第一次尝试每秒获取新数据成功了:

代码语言:javascript
复制
'use strict';

function dataCtrl($scope, $http, $timeout) {
    $scope.data = [];

    (function tick() {
        $http.get('api/changingData').success(function (data) {
            $scope.data = data;
            $timeout(tick, 1000);
        });
    })();
};

当我通过让线程休眠5秒来模拟一个运行缓慢的服务器时,它会等待响应,然后才会更新UI并设置另一个超时。问题是当我重写上面的代码来使用Angular模块和DI来创建模块时:

代码语言:javascript
复制
'use strict';

angular.module('datacat', ['dataServices']);

angular.module('dataServices', ['ngResource']).
    factory('Data', function ($resource) {
        return $resource('api/changingData', {}, {
            query: { method: 'GET', params: {}, isArray: true }
        });
    });

function dataCtrl($scope, $timeout, Data) {
    $scope.data = [];

    (function tick() {
        $scope.data = Data.query();
        $timeout(tick, 1000);
    })();
};

只有在服务器响应很快的情况下,这才能起作用。如果有任何延迟,它就会在没有等待响应的情况下每秒发出1个请求,并且似乎会清除UI。我想我需要使用一个回调函数。我试过了:

代码语言:javascript
复制
var x = Data.get({}, function () { });

但是得到了一个错误:"Error: destination.push不是一个函数“这是基于$resource的文档,但我并不真正理解其中的示例。

我如何让第二种方法起作用?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-03 01:04:41

您应该在query的回调中调用tick函数。

代码语言:javascript
复制
function dataCtrl($scope, $timeout, Data) {
    $scope.data = [];

    (function tick() {
        $scope.data = Data.query(function(){
            $timeout(tick, 1000);
        });
    })();
};
票数 116
EN

Stack Overflow用户

发布于 2014-01-29 13:23:48

较新版本的angular引入了$interval,它在服务器轮询方面甚至比$timeout更好。

代码语言:javascript
复制
var refreshData = function() {
    // Assign to scope within callback to avoid data flickering on screen
    Data.query({ someField: $scope.fieldValue }, function(dataElements){
        $scope.data = dataElements;
    });
};

var promise = $interval(refreshData, 1000);

// Cancel interval on page changes
$scope.$on('$destroy', function(){
    if (angular.isDefined(promise)) {
        $interval.cancel(promise);
        promise = undefined;
    }
});
票数 33
EN

Stack Overflow用户

发布于 2016-08-10 10:02:49

这是我使用递归轮询的版本。这意味着它将在启动下一个超时之前等待服务器响应。此外,当错误发生时,它将继续轮询,但会根据错误的持续时间以一种更宽松的方式进行轮询。

Demo is here

Written more about it in here

代码语言:javascript
复制
var app = angular.module('plunker', ['ngAnimate']);

app.controller('MainCtrl', function($scope, $http, $timeout) {

    var loadTime = 1000, //Load the data every second
        errorCount = 0, //Counter for the server errors
        loadPromise; //Pointer to the promise created by the Angular $timout service

    var getData = function() {
        $http.get('http://httpbin.org/delay/1?now=' + Date.now())

        .then(function(res) {
             $scope.data = res.data.args;

              errorCount = 0;
              nextLoad();
        })

        .catch(function(res) {
             $scope.data = 'Server error';
             nextLoad(++errorCount * 2 * loadTime);
        });
    };

     var cancelNextLoad = function() {
         $timeout.cancel(loadPromise);
     };

    var nextLoad = function(mill) {
        mill = mill || loadTime;

        //Always make sure the last timeout is cleared before starting a new one
        cancelNextLoad();
        $timeout(getData, mill);
    };


    //Start polling the data from the server
    getData();


        //Always clear the timeout when the view is destroyed, otherwise it will   keep polling
        $scope.$on('$destroy', function() {
            cancelNextLoad();
        });

        $scope.data = 'Loading...';
   });
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13671031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档