whenFinished method
Registers callback for the end of the job and returns an unregister
function.
Calls it synchronously with the outcome once the job has finished: after its cleanup, after the whenCancelled listeners of a cancelled job and JobObserver.onFinish, and before anything waiting on done or value resumes. A job cancelled before its start calls it as it is dropped; one that never starts never calls it. An engine that ends the job by hand calls it then, ahead of any cleanup still to run.
Registering does not observe the outcome: a Failed handed to
callback is still answered for, unless somebody observes it — reads
done or value, or calls ignoreFailure. That is what it is for: a
widget that turns a spinner off when the job ends without taking over
a failure the job's owner answers for.
final unregister = job.whenFinished((_) => setState(() => busy = false));
// In dispose(), if the widget goes before the job does:
unregister();
Registering on a finished job calls callback at once, and so does
registering during the pass; one made after the outcome is set but
before the pass, from JobObserver.onFinish say, joins the pass.
Otherwise the registrations, the errors of a callback and unregistering
behave as they do for whenCancelled: each runs once, in registration
order and from a snapshot, and the job releases them as it finishes.
Implementation
@override
void Function() whenFinished(void Function(Outcome<T> outcome) callback) {
final guarded = _guardListener(callback);
if (_finishTold) {
guarded(_outcome!);
return () {};
}
return _finishListeners.add(guarded);
}