0

Hey all i have this code posted here: http://jsfiddle.net/mN6Gy/12/

Problem is it skips numbers in the seconds (goes from 30, 25, 24, 23, 22, 21, 20, 15,...)

and once the seconds reach 00 it start back over on 99, 98, 97, 96...!!

Any help to find this in the code would be great!

Thanks,

David

4

2 回答 2

1

Oh boy, this is was not fun to debug - and I'm not sure I have all the answers...

The issue I found is that you have too many days so your indexes are off.

Options.format: "dd:hh:mm:ss"
> Actually have '119:01:16:18' (for example)

So when you are looping through, all your indexes are off by one - for now. But when the time gets to <100 days, it would be right - I think.

As a hacky solution to see what I mean (and so you may have a place to start the fix), see this editing snippet:

    switch (options.format[i]) {
      case 'h':
        digits[c].__max = ((c-1) % 2 == 0) ? 2: 9;  // <== EDIT
        if (c % 2 == 0)
          digits[c].__condmax = 4;
        break;
      case 'd':
        digits[c].__max = 9;
        break;
      case 'm':
      case 's':
        digits[c].__max = ((c-1) % 2 == 0) ? 5: 9;  // <== EDIT
    }
于 2012-04-28T03:46:09.327 回答
-1

Generally, the code seems to run fine - after x seconds, the counter counts x less. The setInterval() function in your code

setInterval(moveStep(digits.length - 1), 1000);

calls moveStep() every 1000 miliseconds, i.e. every second. However, you cannot expect your computer, your operating system and your browser to be totally precise with miliseconds. Sometimes the event triggers sooner and sometimes it triggers later (especially if you are also running other programs that may interfere or slow down your code). So it just may happen that instead of

counter=2 - 1 second delay - counter=1 - 1 second delay - counter=0

you get

counter=2 - 2 second delay - counter=1 - counter=0

or something like that. In this case, you wouldn't see the counter=1, because it gets immediately redrawn when the next event triggers and counter is set to 0.

One thing you can do is to use setTimeout instead of setInterval, so you get

var callback = function() {
    moveStep(digits.length - 1);
    setTimeOut(callback, 1000);
}

setTimeOut(callback, 1000);

In this case, the timed events won't line up in a queue and then trigger at once, like they did in the previous case. This is because you don't set the interval, but just a timeout - the next event is scheduled to occur 1 second after the current event has finished. This way, the time between two events will always be (approximately) 1 second.

However, the problem here is with the world approximately. In the first case, setInterval() schedules the events to occur 1 second, 2 seconds, 3 seconds etc. from now, so after x seconds, your counter should be decreased by x, although it sometimes doesn't redraw at every step. However, in the second case, when using setTimeout, the little deviations from 1000 miliseconds may slowly build up, so your counter will get decremented by x*1.1 after x seconds, or something like that. In other words, you can't guarantee it to be on time.

To sum it up, you're facing a common problem with setInterval and I don't think there is much to do about it.

于 2012-04-28T02:03:34.917 回答