import 'dart:async'; import 'package:flutter/widgets.dart'; import 'async_typeof.dart'; import 'cancel_future.dart'; class AsyncUtil { AsyncUtil._(); static CancelableFuture retryWithExponentialBackoff( FutureCallback callback, int maxRetry, Predicate predicate) { const Duration initialInterval = Duration(seconds: 1); int retryCount = 0; Timer? timer; void attempt(Completer completer) { callback().then((value) { if (!completer.isCompleted) { completer.complete(value); } }).catchError((error) { if (retryCount < maxRetry && predicate(error)) { retryCount++; Duration nextInterval = initialInterval * (1 << (retryCount - 1)); timer = Timer(nextInterval, () => attempt(completer)); } else { if (!completer.isCompleted) { completer.completeError(error); } } }); } return CancelableFuture((completer) { attempt(completer); }, () { timer?.cancel(); }); } static CancelableFuture retryWhen(FutureCallback callback, int maxRetry, Duration interval, Predicate predicate, [Duration? timeout]) { int retryCount = 0; Timer? timer; Timer? timeoutTimer; void attempt(Completer completer) { callback().then((value) { if (!completer.isCompleted) { completer.complete(value); } }).catchError((error) { if ((maxRetry <= 0 || retryCount < maxRetry) && predicate(error)) { retryCount++; timer = Timer(interval, () => attempt(completer)); } else { if (!completer.isCompleted) { completer.completeError(error); } } }); } return CancelableFuture((completer) { if (timeout != null) { timeoutTimer = Timer(timeout, () { if (!completer.isCompleted) { completer.completeError(TimeoutException('Operation timed out')); } }); } attempt(completer); }, () { timer?.cancel(); timeoutTimer?.cancel(); }); } static CancelableFuture retry(FutureCallback callback, int maxRetry, Duration interval, [Duration? timeout]) { return retryWhen(callback, maxRetry, interval, (error) => true, timeout); } static CancelableFuture delay( FutureCallback callback, Duration interval) { Timer? timer; return CancelableFuture((completer) { timer = Timer(interval, () { callback().then((value) { if (!completer.isCompleted) { completer.complete(value); } }).catchError((error) { if (!completer.isCompleted) { completer.completeError(error); } }); }); }, () { timer?.cancel(); }); } ///实际delay第一次执行的时间为delay+interval static CancelableFuture interval(FutureCallback callback, Duration delay, Duration interval, int times) { Timer? timer; Timer? delayTimer; int counter = 0; void tick(Completer completer) { if (counter < times) { callback().then((value) { if (!completer.isCompleted) { completer.complete(value); } }).catchError((error) { if (!completer.isCompleted) { completer.completeError(error); } }); counter++; } else { timer?.cancel(); } } return CancelableFuture((completer) { delayTimer = Timer(delay, () { timer = Timer.periodic(interval, (Timer t) => tick(completer)); }); }, () { delayTimer?.cancel(); timer?.cancel(); }); } }