launchWhenNextLifecycleEvent<T> method

Future<T> launchWhenNextLifecycleEvent<T>({
  1. LifecycleEvent targetEvent = LifecycleEvent.start,
  2. bool runWithDelayed = false,
  3. Cancellable? cancellable,
  4. required FutureOr<T> block(
    1. Cancellable cancellable
    ),
})

当下一个事件分发时,执行一次给定的block

Implementation

Future<T> launchWhenNextLifecycleEvent<T>(
    {LifecycleEvent targetEvent = LifecycleEvent.start,
    bool runWithDelayed = false,
    Cancellable? cancellable,
    required FutureOr<T> Function(Cancellable cancellable) block}) {
  Completer<T> completer = Completer();
  late final LifecycleObserver observer;
  Cancellable? checkable;
  observer = LifecycleObserver.eventAny((event) async {
    if (event == targetEvent && checkable == null) {
      checkable = makeLiveCancellable(other: cancellable);
      try {
        if (runWithDelayed) {
          await Future.delayed(Duration.zero);
        }
        if (checkable!.isUnavailable) {
          removeLifecycleObserver(observer, fullCycle: false);
          return;
        }
        checkable!.whenCancel.then(
            (value) => removeLifecycleObserver(observer, fullCycle: false));

        final result = block(checkable!);
        if (result is Future<T>) {
          await Future.delayed(Duration.zero);
          if (checkable?.isAvailable == true) {
            final r = await result;
            if (checkable?.isAvailable == true && !completer.isCompleted) {
              completer.complete(r);
            }
          }
        } else {
          completer.complete(result);
        }
      } catch (error, stackTree) {
        if (error != checkable?.reasonAsException && !completer.isCompleted) {
          completer.completeError(error, stackTree);
        }
      }
    } else if (checkable?.isAvailable == true) {
      checkable?.cancel();
    }
  });

  addLifecycleObserver(observer,
      startWith: currentLifecycleState, fullCycle: true);

  final result = completer.future;

  result.whenComplete(
      () => removeLifecycleObserver(observer, fullCycle: false));
  return result;
}