Своё поверх ядра
Если вашей библиотеке нужны своё состояние, очередь или правила
планирования, наследуйте JobBase<T> и JobContextBase. Базовые классы
обеспечивают описанный выше жизненный цикл, а наследники добавляют
поведение библиотеки. Защищённый API даёт доступ к статусу,
ожидающей отмене, дочерним задачам, запуску и завершению. У отмены есть
флаг, определяющий, может ли задача её отклонить. Переопределите
started() и finished() для обработки событий жизненного цикла.
Например, собственный класс задачи может создавать свой тип контекста и предоставлять координатору метод запуска:
final class MyJob<T> extends JobBase<T> { final Future<T> Function(MyContext ctx) _body;
MyJob(this._body, {super.key, super.observer});
@override JobContextBase createContext() => MyContext(this);
@override Future<T> execute(covariant MyContext ctx) => _body(ctx);
// `start` защищён: движок открывает к нему свою дверь. void launch() => start();}
final class MyContext extends JobContextBase { MyContext(super.owner);}
final job = MyJob<int>((ctx) => ctx.wait(load))..launch();wait, join и uncancellable начинают с вызова check(). Переопределите
его, чтобы добавить проверки сразу во все три метода.
Защищённые методы доступны внутри наследников. Если отдельному
координатору нужен такой вызов, предоставьте метод-обёртку в своём классе,
как launch() в примере.
Добавляя собственную обработку ошибок, используйте reportToZone,
чтобы передать ошибку в зону создания задачи, если получателя нет.
Если метод контекста нельзя вызывать из работы, запущенной через
unattended, проверяйте это с помощью throwIfUnattended.
solo использует эти возможности расширения. Полный защищённый API
описан в справке
JobBase.
Отложенный старт
Заголовок раздела «Отложенный старт»Обычный Job планирует свой запуск на следующую микротаску. Если момент
запуска должен выбрать вызывающий код, используйте Job.deferred(body).
Он возвращает DeferredJob<T> с публичным методом start().
Его можно вызвать самостоятельно, поручить запуск очереди или передать
задачу родителю через ctx.run(child), как в примере с дочерней задачей.
final job = Job.deferred<void>((ctx) => ctx.wait(work));// ... позже, или из своей очередиjob.start();