Dart: Is using a zero duration timer the supported way of deferring work to the event loop
Asked Answered
W

1

5

I discovered by experimenting that creating a timer with a duration of 0 allows me to defer work into the event queue. I really like this feature, because it allows avoiding a lot of nasty reentrancy issues. Is this intentional functionality that will not change? Can it be added to the documentation? If not, is there a supported way to do this?

Whitted answered 6/11, 2012 at 3:44 Comment(0)
A
7

Current Answer

The proper way to do this is with scheduleMicrotask(Function callback).

See the API documentation here: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart-async#id_scheduleMicrotask

A great article on async tasks and the event loop is here: https://www.dartlang.org/articles/event-loop/

Old Answer (pre Dart 1.0)

For now, the answer is yes, new Timer(0, callback) is the easiest way to defer a function call.

Soon, hopefully, http://dartbug.com/5691 will be fixed and there will be a better way. The problem with Timer is that the HTML spec says that the callback should happen no sooner than 4ms later. Depending on what you're doing that can be on issue.

Microsoft introduced setImmediate() to solve this. It invokes the callback at the beginning of the next event loop, after any redraws. My preferred solution in Dart is to have Future.immediate() defer until the next event loop, and possibly a function like defer() that takes a callback.

But new Timer(0, f) will still work, even after a better solution is available. I wouldn't mind a lint warning for it though.

Aesculapius answered 6/11, 2012 at 4:3 Comment(2)
Yuck, the 4ms delay is unfortunate. "defer" (and having Future.immediate use it) sounds great. For now, I can code up a defer function that fakes it with a timer. I think this is really important. Getting called back in your forward call has always led to tricky bugs in event driven code. Another thing that would be cool is to be able to create an urgent event that "jumps the queue". Sometimes you want to do this to be able to change state immediately before any queued events are processed.Whitted
I updated my answer to reflect the current state of the async APIs, which is much better. I believe the 4ms delay should be gone on all supported browsers now (IE 10+).Aesculapius

© 2022 - 2024 — McMap. All rights reserved.