我有一个使用JavaScript setInterval
调用的函数,在某些情况下,该函数在未定义间隔间隙的情况下被多次调用(我怀疑这是因为未正确清除间隔,并且我正在创建多个间隔,但我不确定)。
我无法在本地重现该问题。
代码使用Twirl,但基本上是JS:
function refreshCheckInRequests() {
if (interval) { // If there is an interval running stop it.
clearInterval(interval);
}
jsRoutes.controllers.ExtranetSecuredController.findPendingCheckInRequests("@gymId").ajax({ // Ajax call using Play Framework
success: function (data) {
$("#checkin-request-container").html(data);
addRowListeners()
},
error: function (data) {
if (data.status == 401) {
errorSwitchGym("@Messages("extranet.switch.gym")");
//location.reload();
}
else {
unexpectedError(data)
}
},
complete: function() {
interval = initInterval(); // At the end of the call init the interval again
}
});
}
function initInterval() {
return setInterval(function () { refreshCheckInRequests(); },
20000);
}
var interval;
refreshCheckInRequests();
$("#checkin-request-refresh").click(function (event) {
refreshCheckInRequests();
event.preventDefault();
});
我可以改用setTimeout
,因为最后我总是打一次refreshCheckInRequests
,停止间隔,最后创建一个新间隔。
如果使用超时,则必须在超时回调执行结束时再次调用我的函数(就像我现在正在做的那样)。如果出现问题,我的回调将不再被调用。
无论如何,我想知道这里发生了什么。我想念什么吗?难道我做错了什么?有什么建议吗?
答案 0 :(得分:1)
每次调用refreshCheckInRequests
时都要清除当前间隔,但是在调用refreshCheckInRequests
到分配新间隔之间会有一个延迟。由于refreshCheckInRequests
也会在单击元素时运行,因此以下情况可能会导致间隔终止:
findPendingCheckInRequests
findPendingCheckInRequests
运行findPendingCheckInRequests
的响应回来了。 complete
处理程序运行,interval
被分配给新间隔findPendingCheckInRequests
的响应又回来了。 complete
处理程序运行,interval
被分配给新间隔 旧间隔第一个创建的间隔仍在运行,但是不再存在对其的引用,因此第一个间隔将永远重复。
因此,尝试重新分配interval
时清除间隔 ,确保每个新间隔都将始终清除旧间隔(如果正在运行旧间隔):
complete: function() {
clearInterval(interval);
interval = initInterval();
}