whenCancelled method

  1. @override
void Function() whenCancelled(
  1. void callback(
    1. Cancelled
    )
)
override

Registers callback for cancellation and returns an unregister function.

Calls it once, synchronously, with the Cancelled when the job accepts a cancellation, without waiting for the body; a refused cancellation does not call it, and a job that ends Done or Failed releases it uncalled. Registering does not observe a Failed outcome. The callback is synchronous: its error goes to JobObserver.onError and on to the answer, and the future of an async one is not awaited, nor are its errors caught here.

final unregister = job.whenCancelled((cancelled) {
  print(cancelled.reason);
});
// When the listener is no longer needed:
unregister();

See Listening for the cancellation on the outcomes page for when the callback runs and where its errors go.

Implementation

@override
void Function() whenCancelled(void Function(Cancelled) callback) {
  final guarded = _guardListener(callback);

  // `_cancelled` and not `_pendingCancel`: between the mark and the pass
  // that tells the listeners there is a window -- the cascade onto the
  // children -- and a registration made in there belongs in that pass,
  // not ahead of it.
  // Calling it on the spot would run it before everyone who registered
  // earlier and is still waiting. Once the pass has run, `_cancelled` is
  // set and a late registration is called at once, as promised; a job
  // that finished cancelled set it on the way out.
  final cancelled = _cancelled;
  if (cancelled != null) {
    guarded(cancelled);
    return () {};
  }
  // Only a job that finished without a cancellation has nothing left to
  // tell. One that finished cancelled and has not told its listeners yet
  // -- `finished` and `onFinish` run first, and for a job dropped before
  // its start there was no mark to set `_cancelled` earlier -- still has
  // the pass ahead of it, and this registration belongs in it.
  if (isFinished && _outcome is! Cancelled) return () {};
  return _cancelListeners.add(guarded);
}