I'd like to run a function over and over, with a delay in between. How can I do this with Dart?
7 Answers
You can use the Timer
class to schedule one-shot and repeating functions.
Repeating
Here is how you run a repeating function:
import 'dart:async';
main() {
const oneSec = Duration(seconds:1);
Timer.periodic(oneSec, (Timer t) => print('hi!'));
}
The Timer takes two arguments, a duration and a function to run. The duration must be an instance of Duration
. The callback must take a single parameter, the timer itself.
Canceling a repeating timer
Use timer.cancel()
to cancel a repeating timer. This is one reason why timer is passed to the callback run from a repeating timer.
One-shot after a delay
To schedule a one-shot function after a delay (execute once, some time in the future):
import 'dart:async';
main() {
const twentyMillis = Duration(milliseconds:20);
Timer(twentyMillis, () => print('hi!'));
}
Notice the callback for a one-shot timer does not take a parameter.
One-shot as soon as possible
You can also request that a function is run as soon as possible, at least one event-loop tick in the future.
import 'dart:async';
main() {
Timer.run(() => print('hi!'));
}
In HTML
Timers even work in HTML. In fact, window.setTimeout
was removed, so Timer is the only way to run a function in the future.
-
If you are wondering, as I was, how to make a timer that does not depend on a compile time constant, the API docs for the timer has the following solution: const ms = const Duration(milliseconds: 1); var duration = ms * variableMS; return new Timer(duration, handleTimeout); where variableMS is some int set other than as a compile time constant. – scribeGriff Feb 21 '13 at 02:25
-
No constructor 'Timer.repeating' declared in class 'Timer'. dart editor intellisense shows Timer.periodic, I think they changed name – SRN Sep 23 '13 at 20:07
-
1in another post you talk about using repeating futures, which one is the 'best' ? – GameAlchemist Feb 19 '14 at 19:52
-
1Don't forget to call timer.cancel() in dispose() method – stan Aug 07 '20 at 06:04
5 Sec Timer Example
bool isStopped = false; //global
sec5Timer() {
Timer.periodic(Duration(seconds: 5), (timer) {
if (isStopped) {
timer.cancel();
}
print("Dekhi 5 sec por por kisu hy ni :/");
});
}
Call from any function
sec5Timer();
Stop from any function
isStopped = true;
To dispose you can use this code or technique.
@override
void initState() {
_timer = new Timer.periodic(widget.refreshRate,
(Timer timer) => _updateDisplayTime(inheritedWidget));
super.initState();
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}

- 1,927
- 18
- 23
-
4like the bangla printing *Dekhi 5 sec por por kisu hoy ni :/* :D – Al Walid Ashik Sep 14 '21 at 05:26
https://api.dartlang.org/stable/1.24.3/dart-async/Stream/Stream.periodic.html
import 'dart:async';
StreamSubscription periodicSub;
void main() {
periodicSub = new Stream.periodic(const Duration(milliseconds: 500), (v) => v)
.take(10)
.listen((count) => print('tick $count'));
}
or if the counter isn't required just
import 'dart:async';
StreamSubscription periodicSub;
void main() {
periodicSub = new Stream.periodic(const Duration(milliseconds: 500))
.take(10)
.listen((_) => print('tick'));
}

- 623,577
- 216
- 2,003
- 1,567
-
1How can we use an "infinite" periodic function with a "cancel" action. take(10) only generate un recurring function with 10 call – fvisticot Sep 01 '18 at 12:18
-
1
-
In my case, I need to have an "infinite" periodic function. This periodic function run indefinitely until it's stop by an "event" (Click on a button or exiting the page by exemple). In your case the take(10) argument allows only to run the function 10 times and can not be stop before (by example if we need to stop after 3 calls). – fvisticot Sep 02 '18 at 08:29
-
Search for rxdart. You can also use a StreamController to fully control a stream. – Günter Zöchbauer Sep 02 '18 at 08:31
You can also use Future.delayed and await to delay execution:
Future<Null> delay(int milliseconds) {
return new Future.delayed(new Duration(milliseconds: milliseconds));
}
main() async {
await delay(500);
print('Delayed 500 milliseconds');
}

- 9,902
- 6
- 29
- 25
-
1Thanks, but the question was about running a function over and over (repeatedly). – Seth Ladd Mar 04 '18 at 17:32
-
-
1while(true) would eventually block the main thread and application would not be able to respond to user gesture events – alex_z Aug 27 '19 at 08:33
-
I upvoted this because it made me realize this allows me to periodically execute some code and then do another delay. This ensures the "timer" doesn't keep executing while work is still being done (in case of heavy work that may or may not take more time than the scheduled delay). – Sipke Schoorstra Oct 31 '21 at 14:58
-
Like so: https://gist.github.com/sfmskywalker/24e9e30b38d0bf8a8c453e7b38051514 – Sipke Schoorstra Oct 31 '21 at 15:17
import 'dart:async';
Timer interval(Duration duration, func) {
Timer function() {
Timer timer = new Timer(duration, function);
func(timer);
return timer;
}
return new Timer(duration, function);
}
void main() {
int i = 0;
interval(new Duration(seconds: 1), (timer) {
print(i++);
if (i > 5) timer.cancel();
});
}

- 1,391
- 1
- 14
- 24
-
1
-
What's the point of returning the `Timer` from within `function`? The return value is never used, so it just seems to make the code harder to read? – Magnus Jun 20 '21 at 09:31
Opposite to Timer.periodic and Stream.periodic posting my favorite way to handle such a tasks. The advantages:
- the first cycle run instantly
- the callback can work longer than interval without any reentrance headache
Completer<bool> periodic(Duration interval, Function(int cycle) callback) {
final done = Completer<bool>();
() async {
var cycle = 0;
while (!done.isCompleted) {
try {
await callback(cycle);
} catch (e, s) {
log("$e", stackTrace: s);
}
cycle++;
await done.future
.timeout(interval)
.onError((error, stackTrace) => null);
}
}();
return done;
}
main() {
final task = periodic(Duration(seconds: 10), (cycle) async {
/// do the periodic tasks here
});
/// main code here
/// and when going to stop the above periodic call
task.complete(true);
}

- 851
- 9
- 11
Functionally identical code to JavaScript (setInterval, setTimeout, clearInterval and clearTimeout):
// ------------------------------
// Import:
import 'dart:async';
// ------------------------------
// Definitions:
void clearTimeout(Timer timer) {
try {
timer.cancel();
} catch (e) {}
}
Timer setTimeout(VoidCallback fn, int millis) {
Timer timer;
if (millis > 0)
timer = new Timer(new Duration(milliseconds: millis), fn);
else
fn();
return timer;
}
void clearInterval(Timer timer) {
try {
timer.cancel();
} catch (e) {}
}
Timer setInterval(VoidCallback fn, int millis) {
Timer timer;
if (millis > 0)
timer = new Timer.periodic(new Duration(milliseconds: millis), (timer) {
fn();
});
else
fn(); // If millis input is too low, only run function once and stop
return timer;
}
// ---------------------------------
// Example:
int myValue = 0;
Timer counter = setInterval((){ myValue++; }, 50);
setTimeout((){
clearInterval(counter);
}, 5000);

- 11
- 1
- 3