programing

Angular를 사용한 서버 폴링JS

golfzon 2023. 3. 25. 12:05
반응형

Angular를 사용한 서버 폴링JS

저는 AngularJs를 배우려고 해요.매초 새로운 데이터를 얻으려는 첫 시도는 효과가 있었습니다.

'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초간 sleeve 상태로 하여 저속 서버를 시뮬레이트하면 UI를 업데이트하고 다른 타임아웃을 설정하기 전에 응답을 기다립니다.문제는 모듈 작성에 Angular 모듈과 DI를 사용하기 위해 위의 내용을 다시 쓴 경우입니다.

'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초에 1개의 요청을 발송하고 UI를 클리어하는 것처럼 보입니다.콜백 기능을 사용해야 할 것 같아요.나는 시도했다.

var x = Data.get({}, function () { });

에러가 발생했습니다.「 Error : destination 」push is not function." 이것은 $resource에 대한 문서에 근거한 것이지만, 저는 그 예를 잘 이해하지 못했습니다.

두 번째 접근방식은 어떻게 작동합니까?

당신은 전화해야 합니다.tick콜백으로 기능하다query.

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

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

angular의 최신 버전에서는 서버 폴링에 $timeout보다 더 효과적인 $interval이 도입되었습니다.

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

다음은 재귀 폴링을 사용한 버전입니다.즉, 다음 타임아웃을 시작하기 전에 서버 응답을 기다립니다.또, 에러가 발생했을 경우, 폴링은 속행됩니다만, 에러의 지속 시간에 따라서는, 보다 느긋한 방법으로 행해집니다.

데모는 이쪽

여기에 자세히 써넣었다.

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

$interval 서비스를 사용하면 폴링을 쉽게 할 수 있습니다.여기 $120에 대한 상세 문서가 있습니다.
https://docs.angularjs.org/api/ng/service/$interval
$interval을 사용하는 경우의 문제는 $http 서비스 호출 또는 서버 인터랙션을 실행 중이고 $interval 시간보다 지연된 경우 요청이 완료되기 전에 다른 요청이 시작된다는 입니다.
솔루션:
1. 폴링은 단일 비트 또는 Lightweight json과 같이 서버에서 가져오는 단순한 상태여야 합니다.따라서 정의된 인터벌 시간보다 오래 걸리지 않습니다.또한 이 문제를 방지하려면 간격 시간을 적절하게 정의해야 합니다.
2. 어떤 이유로든 다른 요청을 보내기 전에 이전 요청이 종료되었는지 글로벌 플래그를 확인해야 합니다.이 시간 간격은 놓치지만 요청을 섣불리 보내지는 않습니다.
또, 어느 의 값 할 수 .「」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 、 「 」
여기 작업 예가 있습니다.여기서 자세히 설명하다

angular.module('myApp.view2', ['ngRoute'])
.controller('View2Ctrl', ['$scope', '$timeout', '$interval', '$http', function ($scope, $timeout, $interval, $http) {
    $scope.title = "Test Title";

    $scope.data = [];

    var hasvaluereturnd = true; // Flag to check 
    var thresholdvalue = 20; // interval threshold value

    function poll(interval, callback) {
        return $interval(function () {
            if (hasvaluereturnd) {  //check flag before start new call
                callback(hasvaluereturnd);
            }
            thresholdvalue = thresholdvalue - 1;  //Decrease threshold value 
            if (thresholdvalue == 0) {
                $scope.stopPoll(); // Stop $interval if it reaches to threshold
            }
        }, interval)
    }

    var pollpromise = poll(1000, function () {
        hasvaluereturnd = false;
        //$timeout(function () {  // You can test scenario where server takes more time then interval
        $http.get('http://httpbin.org/get?timeoutKey=timeoutValue').then(
            function (data) {
                hasvaluereturnd = true;  // set Flag to true to start new call
                $scope.data = data;

            },
            function (e) {
                hasvaluereturnd = true; // set Flag to true to start new call
                //You can set false also as per your requirement in case of error
            }
        );
        //}, 2000); 
    });

    // stop interval.
    $scope.stopPoll = function () {
        $interval.cancel(pollpromise);
        thresholdvalue = 0;     //reset all flags. 
        hasvaluereturnd = true;
    }
}]);

언급URL : https://stackoverflow.com/questions/13671031/server-polling-with-angularjs

반응형