async_util.dart 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import 'dart:async';
  2. import 'package:flutter/widgets.dart';
  3. import 'async_typeof.dart';
  4. import 'cancel_future.dart';
  5. class AsyncUtil {
  6. AsyncUtil._();
  7. static CancelableFuture<T> retryWithExponentialBackoff<T>(
  8. FutureCallback<T> callback,
  9. int maxRetry,
  10. Duration initialInterval,
  11. Predicate<dynamic> predicate) {
  12. Completer<T> completer = Completer<T>();
  13. int retryCount = 0;
  14. Timer? timer;
  15. void attempt() {
  16. callback().then((value) {
  17. if (!completer.isCompleted) {
  18. completer.complete(value);
  19. }
  20. }).catchError((error) {
  21. if (retryCount < maxRetry && predicate(error)) {
  22. retryCount++;
  23. Duration nextInterval = initialInterval * (1 << (retryCount - 1));
  24. timer = Timer(nextInterval, attempt);
  25. } else {
  26. if (!completer.isCompleted) {
  27. completer.completeError(error);
  28. }
  29. }
  30. });
  31. }
  32. attempt();
  33. return CancelableFuture<T>(() {
  34. timer?.cancel();
  35. });
  36. }
  37. static CancelableFuture<T> retryWhen<T>(FutureCallback<T> callback,
  38. int maxRetry, Duration interval, Predicate<dynamic> predicate) {
  39. Completer<T> completer = Completer<T>();
  40. int retryCount = 0;
  41. Timer? timer;
  42. void attempt() {
  43. callback().then((value) {
  44. if (!completer.isCompleted) {
  45. completer.complete(value);
  46. }
  47. }).catchError((error) {
  48. if (retryCount < maxRetry && predicate(error)) {
  49. retryCount++;
  50. timer = Timer(interval, attempt);
  51. } else {
  52. if (!completer.isCompleted) {
  53. completer.completeError(error);
  54. }
  55. }
  56. });
  57. }
  58. attempt();
  59. return CancelableFuture<T>(() {
  60. timer?.cancel();
  61. });
  62. }
  63. static CancelableFuture<T> retry<T>(
  64. FutureCallback<T> callback, int maxRetry, Duration interval) {
  65. return retryWhen(callback, maxRetry, interval, (error) => true);
  66. }
  67. static CancelableFuture<T> delay<T>(
  68. FutureCallback<T> callback, Duration interval) {
  69. Timer? timer;
  70. return CancelableFuture<T>(
  71. () {
  72. timer?.cancel();
  73. },
  74. futureCompleter: (completer) {
  75. timer = Timer(interval, () {
  76. callback()
  77. .then(completer.complete)
  78. .catchError(completer.completeError);
  79. });
  80. },
  81. );
  82. }
  83. ///实际delay第一次执行的时间为delay+interval
  84. static CancelableFuture<T> interval<T>(FutureCallback<T> callback,
  85. Duration delay, Duration interval, int times) {
  86. Timer? timer;
  87. Timer? delayTimer;
  88. int counter = 0;
  89. Completer<T> completer = Completer<T>();
  90. void tick() {
  91. if (counter < times) {
  92. callback().then((value) {
  93. if (!completer.isCompleted) {
  94. completer.complete(value);
  95. }
  96. }).catchError((error) {
  97. if (!completer.isCompleted) {
  98. completer.completeError(error);
  99. }
  100. });
  101. counter++;
  102. } else {
  103. timer?.cancel();
  104. }
  105. }
  106. delayTimer = Timer(delay, () {
  107. timer = Timer.periodic(interval, (Timer t) => tick());
  108. });
  109. return CancelableFuture<T>(() {
  110. delayTimer?.cancel();
  111. timer?.cancel();
  112. });
  113. }
  114. }