structured_async 0.3.2 copy "structured_async: ^0.3.2" to clipboard
structured_async: ^0.3.2 copied to clipboard

Structured asynchronous programming in Dart.

example/structured_async_example.dart

import 'dart:async';

import 'package:structured_async/structured_async.dart';

Future<int> theAnswer() async => 42;

/// Run with the "cancel" argument to show what happens when
/// a Future gets cancelled.
Future<void> main(List<String> args) async {
  final cancel = args.contains('cancel');
  final startTime = now();

  print('Time  | Message\n'
      '------+--------');

  runZoned(() async {
    await simpleExample(cancel);
    await groupExample(cancel);
  }, zoneSpecification: ZoneSpecification(print: (self, parent, zone, line) {
    parent.print(zone, '${(now() - startTime).toString().padRight(5)} | $line');
  }));
}

Future<void> simpleExample(bool cancel) async {
  // create a cancellable from any async function
  final cancellableAnswer = CancellableFuture(() async {
    // the function can only be cancelled at async points,
    // so returning a number here, for example, would be impossible
    // to cancel! So we call another async function instead.
    return await theAnswer();
  });

  if (cancel) {
    cancellableAnswer.cancel();
  }

  try {
    print('The answer is ${await cancellableAnswer}');
  } on FutureCancelled {
    print('Could not compute the answer!');
  }

  // it is also possible to check if a computation has been cancelled
  // explicitly by calling isComputationCancelled()...
  // Also notice we can use the factory constructor instead of cancellable().
  final cancelFriendlyTask = CancellableFuture.ctx((ctx) async {
    if (ctx.isComputationCancelled()) {
      // the caller will get a FutureCancelled Exception as long as they await
      // after the task has been cancelled.
      return null;
    }
    return 42;
  });

  if (cancel) {
    cancelFriendlyTask.cancel();
  }

  try {
    print('The answer is still ${await cancelFriendlyTask}');
  } on FutureCancelled {
    print('Still cannot compute the answer!');
  }
}

Future<void> groupExample(bool cancel) async {
  final results = <int?>[];

  final group = CancellableFuture.group([
    () async => sleep(Duration(milliseconds: 30), () => 1),
    () async => sleep(Duration(milliseconds: 10), () => 2),
    () async => sleep(Duration(milliseconds: 20), () => 3),
  ], receiver: (int? n) {
    // values are received in the order they are emitted!
    results.add(n);
  });

  if (cancel) {
    // group.cancel();
  }

  try {
    await group;
    print('Group basic result: $results');
  } on FutureCancelled {
    print('Group basic result was cancelled');
  }

  final group2 = CancellableFuture.group([
    () async => print('Started group 2, should print every second, up to 3s.'),
    () => sleep(Duration(seconds: 1), () => print('1 second')),
    () => sleep(Duration(seconds: 2), () => print('2 seconds')),
    () => sleep(Duration(seconds: 3), () => print('3 seconds')),
  ]);

  scheduleMicrotask(() async {
    if (cancel) {
      print('Will cancel group 2 after 1 second, approximately...');
      await sleep(Duration(milliseconds: 1100));
      print('Cancelling!');
      group2.cancel();
    }
  });

  try {
    await group2;
    print('Done');
  } on FutureCancelled {
    print('Group2 interrupted!');
  }
}

int now() => DateTime.now().millisecondsSinceEpoch;

/// Sleep for the given duration of time using small "ticks"
/// to check if it's time to "wake up" yet.
///
/// This is done because it's not possible to cancel a submitted
/// [Future.delayed] call. In the real world, actual async code
/// would be used rather than [Future.delayed] anyway, so this
/// should not be a problem in most applications.
Future<T?> sleep<T>(Duration duration, [T Function()? function]) async {
  final stopTime = now() + duration.inMilliseconds;
  while (now() < stopTime) {
    await Future.delayed(const Duration(milliseconds: 50));
  }
  return function?.call();
}
16
likes
150
pub points
38%
popularity

Publisher

unverified uploader

Structured asynchronous programming in Dart.

Repository (GitHub)
View/report issues

Documentation

API reference

License

Apache-2.0 (license)

More

Packages that depend on structured_async