Breaking change: Removal of window.setTimeout and window.setInterval

1,198 views
Skip to first unread message

Emily Fortuna

unread,
Feb 13, 2013, 3:44:06 PM2/13/13
to General Dart Discussion
Both window.setTimeout, window.setInterval, window.clearTimeout, and window.clearInterval replicate the behavior that is in the Timer and Timer.repeating class. So, we merged the functionality just into Timer. Expect setImmediate to change in the future as well once Future has some additional functionality.

What this means for you, in terms of examples -- in the old version, you would write:
window.setTimeout(() { doStuff(); }, 0);

in the new version you just write:
import 'dart:async';
Timer.run(doStuffCallback);

-----
Some other examples for the change:

Old way: 
var id = window.setTimeout(doStuffCallback, 10);
.... some time later....
window.clearTimeout(id);

id = window.setInterval(doStuffCallback, 1000);
window.clearInterval(id);

New way:
var timer = new Timer(const Duration(milliseconds: 10), doStuffCallback);
... some time later ---
timer.cancel();

timer = new Timer.repeating(const Duration(seconds: 1), doStuffCallback);
timer.cancel();

Seth Ladd

unread,
Feb 13, 2013, 6:12:08 PM2/13/13
to General Dart Discussion
Thanks Emily!

Sorry, I haven't seen the docs yet, but once difference between the VM's timer and the browser's setTimeout: setTimeout has a minimum timeout of 4ms (see MDN)

Any ideas on how we can document this behavior difference? Maybe just a note in the API docs?


--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
 
 

John McCutchan

unread,
Feb 13, 2013, 6:18:56 PM2/13/13
to General Dart Discussion
Timer precision is likely an issue with dart:io timers too. Each OS (Windows, Linux, Mac) has some minimum guaranteed timer resolution. On Windows it's something like 10ms. It's best to think of a timer as being the minimum amount of time you want to have elapsed before the timer fires.

John
--
John McCutchan <jo...@johnmccutchan.com>

Emily Fortuna

unread,
Feb 13, 2013, 7:08:12 PM2/13/13
to mi...@dartlang.org
Yes-- I forgot to mention that in my email. If you need yet even more immediate execution, you still have 
window.setImmediate, which does browser-specific modifications to attempt to run immediately after the current frame rewinds. I've written about this in the documentation for setImmediate: https://codereview.chromium.org/12253011/diff/2001/tools/dom/templates/html/impl/impl_Window.darttemplate  Should we mention this in the timer documentation, too?



On Wed, Feb 13, 2013 at 3:12 PM, Seth Ladd <seth...@google.com> wrote:

John Messerly

unread,
Feb 13, 2013, 8:01:28 PM2/13/13
to mi...@dartlang.org
On Wed, Feb 13, 2013 at 3:18 PM, John McCutchan <jo...@johnmccutchan.com> wrote:
Timer precision is likely an issue with dart:io timers too. Each OS (Windows, Linux, Mac) has some minimum guaranteed timer resolution. On Windows it's something like 10ms. It's best to think of a timer as being the minimum amount of time you want to have elapsed before the timer fires.

Windows has high resolution timers, but it's a different API. See QueryPerformanceCounter and QueryPerformanceFrequency

IIRC, it's been support for a long time (win 2k according to docs).

John Messerly

unread,
Feb 13, 2013, 8:02:26 PM2/13/13
to mi...@dartlang.org
Nevermind... we're talking about callbacks. I'd swear there's a way to do it but I can't recall offhand :)

W. Brian Gourlie

unread,
Feb 20, 2013, 5:09:40 PM2/20/13
to mi...@dartlang.org
So if I want to use a timer that runs once and has no chance of being canceled, I just have:

new Timer(const Duration(milliseconds: 250), () => hideSuggestions());

It seems weird and counter-intuitive to instantiate a new object just to perform an action.

Should I be doing this differently?

w.brian

Joao Pedrosa

unread,
Feb 21, 2013, 4:21:35 AM2/21/13
to mi...@dartlang.org
Hi,

On Wed, Feb 20, 2013 at 7:09 PM, W. Brian Gourlie <bgou...@gmail.com> wrote:
So if I want to use a timer that runs once and has no chance of being canceled, I just have:

new Timer(const Duration(milliseconds: 250), () => hideSuggestions());

It seems weird and counter-intuitive to instantiate a new object just to perform an action.

Should I be doing this differently?

I could suggest to use a shortcut for accessing such utility methods. Transitioning to the new Timer class was easy for me as I needed to change it in just 4 places:

class Util {

  timer(fn(), [n = 50]) {
    return new DA.Timer(new Duration(milliseconds: n), fn);
  }

  interval(fn(), [n = 50]) {
    return new DA.Timer.repeating(new Duration(milliseconds: n), (t) => fn());
  }

}

You can put one Util object on a top level variable and go from there.

I have a bunch of misc methods on a "DRImpl" class that I access thru the DR top level variable. You can name yours after your project or some such.

Then I access mine like DR.timer(() => print("Hey"));

I also have a couple of classes that are abstractions over Timer called EventDelayer and EventRepeater.

All my Timer usage comes from those 4 places. The cool thing about the Stream API used by Timer is being able to cancel them more easily. So I was able to do away with stopTimer and stopInterval methods.

I recently added an Animation class that hooked up to the EventDelayer one, for example. The EventRepeater one I use for simulating mouse clicks and keyboard input at least.

I think other frameworks come up with plenty of abstractions around Timer. It's good to have some of our own if it helps us to understand the trade-offs as well.

Cheers,
Joao

W. Brian Gourlie

unread,
Feb 21, 2013, 11:47:24 AM2/21/13
to mi...@dartlang.org
I could suggest to use a shortcut for accessing such utility methods.

Right.  I bring it up more as a question about API design and if it's a good idea to have a constructor invoke some action.  It seems similar to past discussions about doing similar things in getters/setters.

w.brian

Bob Nystrom

unread,
Feb 21, 2013, 12:53:54 PM2/21/13
to General Dart Discussion

On Thu, Feb 21, 2013 at 1:21 AM, Joao Pedrosa <joaop...@gmail.com> wrote:
I could suggest to use a shortcut for accessing such utility methods. Transitioning to the new Timer class was easy for me as I needed to change it in just 4 places:

class Util {

  timer(fn(), [n = 50]) {
    return new DA.Timer(new Duration(milliseconds: n), fn);
  }

  interval(fn(), [n = 50]) {
    return new DA.Timer.repeating(new Duration(milliseconds: n), (t) => fn());
  }

}

We do something similar in pub. Maybe we should add something like this to dart:async? Filed a bug:


Cheers,

- bob
Reply all
Reply to author
Forward
0 new messages