我的页面顶部有一个进度条,我用它来显示用于刷新所有图表的1分钟计时器。我遇到的问题是它似乎永远不会一致。
function headerBar() {
var progressbar = $('#timerBar');
progressbar.progressbar({
value: 0
});
function progress() {
var val = progressbar.progressbar('value') || 0;
progressbar.progressbar('value', val + 5);
if (val < 99) {
setTimeout(progress, 3000);
}
}
progress();
}
headerBar();
setInterval(function () {
headerBar();
}, 60 * 1000);
它第一次运行正常,但是第二次似乎需要花费1/2的时间,并且每次之后似乎都会减少计数时间。
这是fiddle
答案 0 :(得分:3)
乌拉!你正陷入一种竞争状态。由于setTimeout()
无法保证每隔3000毫秒调用setInterval()
(即使它确实如此,您仍然会遇到此问题),最有可能发生的是您的间隔调用{{1} }} headerBar()
设法阻止自己添加更多超时!这是一个清除它的时间表:
您的进度条为95!
progress()
- &gt;我最好打电话给timeout1
!
progress()
- &gt;将进度条设置为progress()
! val + 5 = 100
?是啊!我最好设置超时再次给自己打电话
val(95) < 99
- &gt;你的时间到了! interval
!
headerBar()
- &gt;我将进度设置为0,然后开始更多headerBar()
!
progress()
- &gt;将进度条设置为5!超时再次给自己打电话!
progress()
- &gt;将进度条设置为10!超时再次给自己打电话! (哎呀,我从来没有到progress()
再一次停止打电话给自己!)
val > 99
- &gt;现在是时候走得更快了! interval
!
但你怎么解决这个问题呢?首先,您需要更改headerBar()
支票以使用progress()
。这仍然无法避免诸如将20个超时调用时间超过一个时间间隔的问题 - 您需要某种方式来指示您的val + 5 < 99
停止所有进展。
执行此操作的一种方法是向progress()
添加一些完整性检查:
headerBar()
然而,这是一个非常黑客的解决方案。更优雅的是使用封口!
function headerBar() {
var progressbar = $('#timerBar');
var lastProgress = 0;
progressbar.progressbar({
value: lastProgress
});
function progress() {
var val = progressbar.progressbar('value') || 0;
if (val != lastProgress) {
// Someone's modified the bar! I best stop before I do too much progress!
return;
}
progressbar.progressbar('value', val + 5);
if (val + 5 < 99) {
setTimeout(progress, 3000);
}
}
progress();
}
一般情况下,您仍然可以通过修改var headerBar = (function () {
var inProgress = false;
var progressbar = $('#timerBar'); // Save some trees by calling jQuery selection only once!
return function headerBar() {
if (inProgress) {
clearTimeout(inProgress);
inProgress = false;
}
progressbar.progressbar({
value: 0
});
function progress() {
var val = progressbar.progressbar('value') || 0;
progressbar.progressbar('value', val + 5);
if (val < 99) {
inProgress = setTimeout(progress, 3000);
}
}
progress();
}
})();
来简单地告诉您何时完成来消除间隔(这会在您的时间安排中引入一些误差)。
headerBar()
答案 1 :(得分:1)
发表评论:
(function () {
var progressbar;
function headerBar() {
progressbar = $('#timerBar');
progressbar.progressbar({
value: 0
});
function progress() {
var val = progressbar.progressbar('value') || 0;
progressbar.progressbar('value', val + 5);
if (val < 99) {
setTimeout(progress, 3000);
}
}
progress();
}
headerBar();
setInterval(function () {
progressbar.progressbar('value', 0);
}, 60 * 1000);
})();
答案 2 :(得分:0)
你需要一个明确的间隔..像这样
function headerBar() {
var progressbar = $('#timerBar');
progressbar.progressbar({
value: 0
});
function progress() {
var val = progressbar.progressbar('value') || 0;
progressbar.progressbar('value', val + 5);
if (val < 99) {
setTimeout(progress, 3000);
}
}
progress();
clearInterval()
}
headerBar();
setInterval(function () {
headerBar();
}, 60 * 1000);
SitePoint here
上的setTimeout的更多示例