jquery-dotimeout icon indicating copy to clipboard operation
jquery-dotimeout copied to clipboard

Problems when called from inside a handler

Open iangilman opened this issue 13 years ago • 4 comments

Great plugin! One issue:

In this example:

$.doTimeout("foo", 100, function() {
    log("in");
    $.doTimeout("foo", 1000, function() {
        log("out");
    });
});

... the inner doTimeout should clear away any others with the same ID, but it does not. Wrapping the inner doTimeout in a setTimeout fixes it, so I assume it has to do with setting up a new doTimeout from within its own handler.

Minimal test case:

http://jsfiddle.net/MmJwj/

I suppose it may look contrived, but it's from a real use-case; I can give more detail if needed.

Thanks.

iangilman avatar Oct 18 '11 20:10 iangilman

Can you describe, in plain english, what you're trying to do?

cowboy avatar Oct 18 '11 20:10 cowboy

Sure! The scenario is we have a magazine webapp, and as we're flipping through the pages, we want a little box to appear (after a small delay) and then disappear later (after a longer delay). The code above works fine if all you do is flip one page; you get "in" after 100ms, and then "out" 1000ms later.

If, however, you flip a number of pages quickly, we want the little box to stay up the entire time. With the code above, the box comes on when it's supposed to, but it disappears 1000ms later, even though there have been more recent $.doTimeout("foo", ...) calls in the intervening time. I was expecting that those intervening calls would have wiped clear the initial 1000ms timer, so the box only disappears 1000 ms after the last "in" rather than the first. If I add a setTimeout(..., 1) around that inner doTimeout, I get the result I was expecting.

Does that clarify?

iangilman avatar Oct 18 '11 21:10 iangilman

Ok, I looked at my code. It seems like I never accounted for a scenario in which the same id would be used in multiple overlapping timeouts. As a result, this isn't going to work unless I significantly refactor the code. Which I can't do right now, but will add to my list of future updates.

That being said, take a look at my Throttle/Debounce plugin. It should allow you to do pretty much what you're trying to do. See this example:

http://jsfiddle.net/cowboy/tJkX8/

cowboy avatar Oct 19 '11 13:10 cowboy

Thanks for the suggestion. Here's what I ended up going with:

clearTimeout(this.pageNumberTimeout);
this.pageNumberTimeout = setTimeout(function() {
    $pn.stop(true).fadeIn(); 
    self.pageNumberTimeout = setTimeout(function() {
        self.pageNumberTimeout = null;
        $pn.stop(true).fadeOut("slow");
    }, 3000);
}, 300);

... so no rush on fixing this bug on our account. I figure I'm probably not the only one who wants to do this sort of thing (I'll call it a "nested debounce"), so probably worth fixing at some point.

Thanks again for all the great libraries! We're using a few of them in our project, which includes the Playboy Archive webapp:

http://blog.iangilman.com/2011/05/making-iplayboy.html

... and the Rolling Stone Archive:

http://archive.rollingstone.com

iangilman avatar Oct 19 '11 16:10 iangilman