计时器上的jQuery UI进度条 [英] jQuery UI progressbar on a timer

查看:59
本文介绍了计时器上的jQuery UI进度条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的页面顶部有一个进度条,我用它来显示用于刷新所有图表的1分钟计时器。我遇到的问题是它似乎永远不会一致。

I have a progressbar on the top of my page that I'm using to display the 1 minute timer used to refresh all the charts. The problem I'm having is that it never seems to be consistent.

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的时间之后的时间似乎可以减少计算时间。

The first time it runs fine, but the 2nd time seems to take 1/2 as long and every time after that seems to shave off time from the count.

这里是小提琴

推荐答案

欢乐!你正陷入一种竞争状态。由于 setTimeout()不能保证每隔3000毫秒调用一次像 setInterval()(即使它确实如此,你也是' d仍然会遇到这个问题),最有可能发生的是你的间隔在 progress() headerBar() >设法阻止自己添加更多超时!以下是清除此问题的时间表:

Hurray! You're running into a kind-of race condition. Since setTimeout() does not guarantee to call every 3000ms like setInterval() (and even if it did, you'd still be subject to this problem), what most likely happens is that your interval calls headerBar() before progress() manages to stop itself from adding more timeouts! Here's a timeline to clear this up:

您的进度条为95!

timeout1 - >我最好打电话给进度()

timeout1 -> I better call progress()!

progress() - >将进度条设置为 val + 5 = 100 val(95)< 99 ?是啊!我最好设置超时再次给自己打电话

progress() -> Set progress bar to val + 5 = 100! val(95) < 99 ? Yeah! I better set a timeout to call myself again

interval - >你的时间到了! headerBar()

interval -> Thy time is up! headerBar()!

headerBar() - >我将进度设置为0,然后开始更多 progress()

headerBar() -> I set the progress to 0, and start more progress()!

进度( ) - >将进度条设置为5!超时再次给自己打电话!

progress() -> Set progress bar to 5! Timeout to call myself again!

进度() - >将进度条设置为10!超时再次给自己打电话! (哎呀,我从来没有得到 val> 99 来停止自己多次打电话!)

progress() -> Set progress bar to 10! Timeout to call myself again! (Oops, I never got to val > 99 to stop calling myself repeatedly!)

时间过去了.. 。

区间 - >现在是时候更快了! headerBar()

interval -> It's time to go FASTER! headerBar()!

但是你如何解决这个问题?那么,首先,您需要更改 progress()检查以使用 val + 5< 99 。这仍然无法避免诸如调用20次超时超过一个间隔之类的问题 - 你需要某种方式来发出信号 progress()以停止所有进展。

But how do you solve this problem? Well, firstly, you'll want to change your progress() check to use val + 5 < 99. That still won't save you from problems like calling 20 timeouts taking longer than your one interval - you'll need some way to signal your progress() to stop with all the progressing.

这样做的一种方法是将一些健全性检查添加到 headerBar()

One way to do this would be to add some sanity checks to 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();
}

然而,这是一个非常hacky的解决方案。更优雅的是使用闭包!

This is a very hacky solution, however. A much more elegant one would be to use a closure!

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()来告诉你它何时完成。

In general though, you could still work on eliminating your interval(this would introduce a slight error in your timing), by modifying headerBar() to simply tell you when it's done.

// Pass the jQuery element so you not only have to select it once, but don't depend on the headerBar knowing where to look for it.
var headerBar = (function (progressbar) {
    return function headerBar(callback) {
        progressbar.progressbar({ value : 0 });
        (function progress() {
            var newVal = (progressbar.progressbar('value') || 0) + 5;
            progressbar.progressbar('value', newVal);
            if (newVal < 99) setTimeout(progress, 3000);
            else callback();
        })();
    }
})($('#timerBar'));

function heavyLifting() {
    // get stuff, etc
    headerBar(heavyLifting);
}

这篇关于计时器上的jQuery UI进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆