我想在一段时间内调用一个方法。我收到堆栈溢出错误。我做错了什么:
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/
答案 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);});