每 x 秒的颤振运行函数

在我的 flutter 应用程序中,我想每10秒检查一次我的 api。我发现 这篇文章每 x 次运行一个函数,并执行以下操作:

class _MainPage extends State<MainPage> {
int starter = 0;


void checkForNewSharedLists(){
// do request here
setState((){
// change state according to result of request
});


}


Widget build(BuildContext context) {
Timer.periodic(Duration(seconds: 15), (Timer t) => checkForNewSharedLists());
}
}

不幸的是,请求堆积如山: 在第一轮重新启动应用程序后,有两个请求到 api,第二轮是四个请求,第三轮是八个请求,以此类推..。

有人知道怎么修吗?

73357 次浏览

build()可以而且通常会被调用不止一次,并且每次都会创建一个新的 Timer.periodic

你需要把代码从 build()中移出来

Timer? timer;


@override
void initState() {
super.initState();
timer = Timer.periodic(Duration(seconds: 15), (Timer t) => checkForNewSharedLists());
}


@override
void dispose() {
timer?.cancel();
super.dispose();
}

更好的做法是将这些代码完全从 API 层或类似的小部件中移出,并使用 StreamBuilder在更新数据的情况下更新视图。

使用 Cron lib,它将定期运行,但是 Timer 和 Cron 之间有一个区别,

Timer: 它在给定的时间间隔内运行任务,无论是秒、分钟还是小时。

Cron: 它用于更复杂的时间间隔,例如: 如果一个任务需要在一个小时的特定时间内运行。让我们看看图表

enter image description here

上图有一个星号,表示出现在特定位置的数字。

import 'package:cron/cron.dart';


main() {
var cron = new Cron();
cron.schedule(new Schedule.parse('*/3 * * * *'), () async {
print('every three minutes');
});
cron.schedule(new Schedule.parse('8-11 * * * *'), () async {
print('between every 8 and 11 minutes');
});
}

上面的例子取自存储库,它很好地解释了第一个 '*'表示分钟,类似于图中所示的小时等等。

一小时的另一个例子是 Schedule.parse(* 1,2,3,4 * * *),这个时间表将在每天的凌晨1点,2点,3点和4点运行。

以供参考 Https://code.tutsplus.com/tutorials/scheduling-tasks-with-cron-jobs——net-8800

Timer 可以正常工作,但也可以使用 Stream 定期执行一个函数:

final Stream _myStream =
Stream.periodic(const Duration(seconds: x), (int count) {
// Do something and return something here
});

见: https://api.flutter.dev/flutter/dart-async/Stream/Stream.periodic.html

我在找代码来运行一个函数每 n 秒运行一次,总共是 x 秒。此外,我还增加了一个功能,如果周期函数在总计时器运行之前返回成功,就可以取消计时器。下面是如何解决这个问题:

bool success = false;
bool done = false;
Future.delayed(const Duration(seconds: n), () {
done = true;
print("Timeout");
});
await Stream.periodic(const Duration(seconds: x)).takeWhile((_) => !done).forEach((_) async
{
success = await FunctionYouWantToExecutePeriodicly();
done = success; // only if you want to finish the function earlier
});