每5秒调用一次服务器 - 返回堆栈溢出错误

时间:2014-03-18 12:08:00

标签: angularjs

我想在一段时间内调用一个方法。我收到堆栈溢出错误。我做错了什么:

html:

<div ng-app="myApp" ng-controller="Ctrl">
    <span>{{calledServer}}</span>
</div>

js:

var app = angular.module('myApp', []);

app.controller("Ctrl", function($scope, repo, poollingFactory) {
    $scope.calledServer;
    $scope.calledServer = poollingFactory.callFnOnInterval(function() {return repo.callServer(5);});
});

app.factory("repo", function() {

    function callServer(id){
        return "call server with id " + id;   
    }

    return {
        callServer: callServer
    };
});

app.factory("poollingFactory", function($timeout) {

    var timeIntervalInSec = 5;

    function callFnOnInterval(fn, timeInterval) {

        $timeout(callFnOnInterval, 1000 * timeIntervalInSec);
        callFnOnInterval(fn, timeIntervalInSec);
    };

    return {
        callFnOnInterval: callFnOnInterval
    };
});

jsfiddle:http://jsfiddle.net/fq4vg/423/

2 个答案:

答案 0 :(得分:8)

您有一个递归调用,不会检查任何先决条件。

您的函数的带注释版本:

function callFnOnInterval(fn, timeInterval) {

  //Schedule a call to 'callFnOnInterval' to happen in one second
  // and return immediately
  $timeout(callFnOnInterval, 1000 * timeIntervalInSec);

  //Immediately make a call to 'callFnOnInterval' which will repeat
  // this process ad-infinitum
  callFnOnInterval(fn, timeIntervalInSec);

};

因为你继续递归地将调用推送到堆栈并且永远不会返回,所以最终会耗尽空间。

由于$timeout服务会返回一个承诺,因此您可以使用它来完成更多工作。

以下是您的服务应该是什么样子:

app.factory("poollingFactory", function ($timeout) {

   var timeIntervalInSec = 5;

   function callFnOnInterval(fn, timeInterval) {

       var promise = $timeout(fn, 1000 * timeIntervalInSec);

       return promise.then(function(){
           callFnOnInterval(fn, timeInterval);
       });
   };

   return {
       callFnOnInterval: callFnOnInterval
   };
});

这是一个示例jsFiddle来演示:http://jsfiddle.net/jwcarroll/cXX2S/

关于上述代码的一些注释。

您正尝试将范围属性值设置为callFnOnInterval的返回值,但这不会起作用。首先,它不会返回任何东西。其次,因为它是异步调用,所以它最多可以返回promise

答案 1 :(得分:4)

你的超时方法正在调用自己,直到他的空间不足。

如果你想每x秒做一些事情,请使用$ interval方法。

app.factory("poollingFactory", function($interval) {

var timeIntervalInSec = 5;

function callFnOnInterval(fn, timeInterval) {
    return $interval(fn, 1000 * timeIntervalInSec);        
};

return {
    callFnOnInterval: callFnOnInterval
};
});

顺便说一句,要将方法的结果返回到scope属性,您必须将调用更改为:

 poollingFactory.callFnOnInterval(function() {return $scope.calledServer = repo.callServer(5);});