flushDefers function
FutureOr
flushDefers({
- void onActionStart(
- dynamic key,
- String? category
- void onActionDone(
- dynamic key,
- String? category
- void onError(
- dynamic ex,
- StackTrace st
- Duration? repeatLater,
Force all deferred task (queued by defer) to execute. If the task given in defer returns an instance of Future, this method will wait until it completes.
onActionStart
- (optional) If specified, it is called when an action starts.onActionDone
- (optional) If specified, it is called when an action has been done.onError
- (optional) used to process the error thrown by a deferred task. If not specified, the exception won't be caught and will terminate this method.repeatLater
- If specified, it will continue to flush any new deferred function (registered via defer when flusing existing deferred functions). Before continue, it will wait the duration specified inrepeatLater
. Default: null (not to repeat).
Implementation
FutureOr flushDefers({void onActionStart(key, String? category)?,
void onActionDone(key, String? category)?,
void onError(ex, StackTrace st)?, Duration? repeatLater}) {
if (_defers.isEmpty && _runnings.isEmpty) return null;
final ops = <Future>[],
defers = _defers;
_defers = HashMap<_DeferKey, _DeferInfo>();
for (final dfkey in defers.keys) {
try {
final di = defers[dfkey]!;
di.timer.cancel();
final key = dfkey.key,
category = dfkey.category;
onActionStart?.call(key, category);
final exec = _executor;
if (exec != null) {
final op = exec(key, di.task, category, onError: onError,
onActionDone: onActionDone == null ?
null: () => onActionDone(key, category));
if (op is Future) ops.add(op);
} else {
var op = di.task(key);
if (op is Future) {
Future ft = op;
if (onActionDone != null)
ft = ft.then((_) => onActionDone(key, category));
if (onError != null)
ft = ft.catchError(onError);
ops.add(ft);
} else {
onActionDone?.call(key, category);
}
}
} catch (ex, st) {
if (onError != null) onError(ex, st);
else rethrow;
}
}
ops.addAll(_runnings);
Future result = Future.wait(ops); //wait => run in parallel
if (repeatLater != null) //spec: null => not repeat
result = result.then(
(_) => Future.delayed(repeatLater,
() => flushDefers(onActionStart: onActionStart,
onActionDone: onActionDone, onError: onError,
repeatLater: repeatLater)));
return result;
}