withDelay method
Future<T>
withDelay(
- Duration minOperationTime, {
- Duration threshold = const Duration(milliseconds: 50),
- @Deprecated("Will be removed in version 2.0.0, use " "the 'threshold' parameter instead.") int thresholdInMillis = 50,
If the time it takes for this to complete is less than
minOperationTime
, then a Future.delayed is awaited for
the remaining time. The delay also affects any errors of this Future.
The Future returned by this method will take at least
as much time as
specified by minOperationTime
to complete.
Implementation
Future<T> withDelay(
Duration minOperationTime, {
Duration threshold = const Duration(milliseconds: 50),
@Deprecated(
"Will be removed in version 2.0.0, use "
"the 'threshold' parameter instead.",
)
int thresholdInMillis = 50,
}) async {
// TODO(obemu): remove/change the asserts and if condition in v2.0.0
// minOperationTime is less than 1 millisecond, therefore
// we do not add a fake delay.
if (minOperationTime.inMilliseconds < 1) return this;
assert(minOperationTime < const Duration(minutes: 10));
assert(minOperationTime.inMilliseconds >= thresholdInMillis);
// Can be removed in v2.0.0, once [thresholdInMillis] is removed.
if (50 != thresholdInMillis) {
if (const Duration(milliseconds: 50) != threshold)
throw ArgumentError.value(
thresholdInMillis,
"thresholdInMillis",
"Cannot provide a value for 'thresholdInMillis' and "
"'threshold', you should only use the 'threshold' parameter",
);
threshold = Duration(milliseconds: thresholdInMillis);
}
Result<T> res;
final watch = Stopwatch();
watch.start();
try {
res = Result.value(await this);
// Forward error objects of any type.
// ignore: avoid_catches_without_on_clauses
} catch (err, st) {
res = Result.error(err, st);
} finally {
watch.stop();
}
final delta = minOperationTime - watch.elapsed;
// Only wait if we have at least threshold.
if (delta >= threshold) {
// TODO(obemu): Maybe find a better fix for the following hack.
// If the operation completed too fast then we wait for
// [minOperationTime], because waiting for [delta]
// in this case may not work (depends on the platform and
// compilation type) so that [withDelay] actually causes a delay of at
// least [minOperationTime].
final delay = watch.elapsed < const Duration(milliseconds: 100)
? minOperationTime
: delta;
await Future.delayed(delay);
}
if (res.asError case final ErrorResult err)
throw Error.throwWithStackTrace(err.error, err.stackTrace);
return res.asValue!.value;
}