AngularJS global http polling service

前端 未结 3 1710
伪装坚强ぢ
伪装坚强ぢ 2020-12-12 15:55

I\'m building a web app using AngularJS. The app needs to poll a URL that returns JSON data and make that data available to any part of the app. From what I\'ve read so far,

相关标签:
3条回答
  • 2020-12-12 16:11

    Here is an angular poller service on Github that can be easily injected into your controller.

    To install: bower install angular-poller.

    Since you want to start a global polling service that runs in the background forever, you can do:

    // Inject angular poller service.
    var myModule = angular.module('myApp', ['poller']);
    
    // The home/init controller when you start the app.
    myModule.controller('myController', function($scope, $resource, poller) {
    
        // Define your resource object.
        var myResource = $resource(url[, paramDefaults]);
    
        // Create and start poller.
        var myPoller = poller.get(myResource);
    
        // Update view. Most likely you only need to define notifyCallback.
        myPoller.promise.then(successCallback, errorCallback, notifyCallback);
    });
    

    Now it will run in the background forever until you call myPoller.stop() or poller.stopAll().

    If you want to use the callback data of this poller in other controllers, you can simply do:

    myModule.controller('anotherController', function($scope, $resource, poller) {
    
        /* 
         * You can also move this to a $resource factory and inject it
         * into the controller so you do not have to define it twice.
         */
        var sameResource = $resource(url[, paramDefaults]);
    
        /* 
         * This will not create a new poller for the same resource
         * since it already exists, but will simply restarts it.
         */
        var samePoller = poller.get(sameResource);
    
        samePoller.promise.then(successCallback, errorCallback, notifyCallback);
    });
    
    0 讨论(0)
  • 2020-12-12 16:21

    I forked @ValentynShybanov's factory code and added intervals calls (every second, every 5 secs, etc), also you can stop and start the poller as you wish:

    http://plnkr.co/edit/EfsttAc4BtWSUiAU2lWf?p=preview

    app.factory('Poller', function($http, $timeout) {
      var pollerData = {
        response: {},
        calls: 0,
        stop: false
      };
    
      var isChannelLive = function() {
        $http.get('data.json').then(function(r) {
          if (pollerData.calls > 30 && pollerData.stop === false) { // call every minute after the first ~30 secs
            var d = new Date();
            console.log('> 30: ' + d.toLocaleString() + ' - count: ' + pollerData.calls);
            pollerData.calls++;
            $timeout(isChannelLive, 10000);
          } else if (pollerData.calls > 15 && pollerData.calls <= 30 && pollerData.stop === false) { // after the first ~15 secs, then call every 5 secs
            var d = new Date();
            console.log('> 15 & <= 30: ' + d.toLocaleString() + ' - count: ' + pollerData.calls);
            pollerData.calls++;
            $timeout(isChannelLive, 5000);
          } else if (pollerData.calls <= 15 && pollerData.stop === false) { // call every 1 second during the first ~15 seconds
            var d = new Date();
            console.log('<= 15: ' + d.toLocaleString() + ' - count: ' + pollerData.calls);
            pollerData.calls++;
            $timeout(isChannelLive, 1000);
          }
    
          pollerData.response = r.data;
        });
    
      };
      var init = function() {
        if (pollerData.calls === 0) {
          pollerData.stop = false;
          isChannelLive();
        }
      };
      var stop = function() {
        pollerData.calls = 0;
        pollerData.stop = true;
      };
    
      return {
        pollerData: pollerData, // this should be private
        init: init,
        stop: stop
      };
    });
    
    0 讨论(0)
  • 2020-12-12 16:31

    Here my solution:

    app.factory('Poller', function($http, $timeout) {
      var data = { response: {}, calls: 0 };
      var poller = function() {
        $http.get('data.json').then(function(r) {
          data.response = r.data;
          data.calls++;
          $timeout(poller, 1000);
        });      
      };
      poller();
    
      return {
        data: data
      };
    });
    

    (calls just to show that polling is been done)

    http://plnkr.co/edit/iMmhXTYweN4IrRrrpvMq?p=preview

    EDIT: As Josh David Miller suggested in comments, dependency on this service should be added in app.run block to ensure polling is done from start:

    app.run(function(Poller) {});
    

    And also moved scheduling of next poll after previous call finished. So there would not be "stacking" of calls in case if polling hangs for a long time.

    Updated plunker.

    0 讨论(0)
提交回复
热议问题