class Job<T> implements JobHandle {
constructor(func: JobFunc<T>, options?: { parent?: Job<any> })
}
A cancellable unit of work with optional cancellation hierarchy.
Cancellation is cooperative, meaning the user has to define pause/suspension points in the task via the pause()
or ensureActive()
methods or by checking isActive
.
Cancelling a parent Job will cancel all children Jobs launched with the job defined as its parent. All children must also cooperatively check for cancellation.
A parent job will not wait for any children jobs unless explicitly awaited on in the provided JobFunc
. In this instance, if the parent completes before its child has completed, the parent will be marked as completed and the children will be cancelled at the next pause point.
If an exception is thrown during a JobFunc, the job will cancel itself and its children and then rethrow the exception to be handled by the user.
Running a job more than once will result in a JobCancellationException
.
Note: When adding a try/catch mechanism inside of a JobFunc
, make sure to rethrow any JobCancellationException
exceptions, otherwise job cancellation will not work as intended.
static isCancelled = (outcome: Outcome<unknown>): outcome is OutcomeError<JobCancellationException>
A type guard that returns true if the given outcome was cancelled. This type guard ensures the error is a JobCancellationException
get isActive(): boolean
Returns true if both the parent job (if one exists) and the current job are both active. A job is active at creation and remains active until it has completed or been cancelled.
get isCompleted(): boolean
Returns true if the job was completed successfully
get isCancelled(): boolean
Returns true if the job was cancelled for any reason, either by explicit invocation of cancel or because its parent was cancelled. This does not imply that the job has fully completed because it may still be finishing whatever it was doing and waiting for its children to complete.
ensureActive()
Checks if the parent job and current job are active and throws JobCancellationException
if either are inactive.
Note: This should only be used inside of a JobFunc
.
get childCount(): number
The current number of active children jobs.
launch<R>(func: JobFunc<R>): Job<R>
Creates and returns a new job with the current job as the parent.
launchAndRun<R>(func: JobFunc<R>): Promise<Outcome<R>>
Creates a new job with the current job as the parent and executes it returning its result.
Note: This should only be used inside of a JobFunc
.
async run(): Promise<Outcome<T>>
Execute the job and return its result.
run
handles all JobCancellationException
and will return an Outcome.Error
if a cancellation occurs.
async runWithTimeout(milliseconds: number): Promise<Outcome<T>>
Executes the job and cancels the job if it takes longer than the timeout to complete/cancel.
async pause<R>(func: Promise<R>): Promise<R>
Await a given func
and ensures the job is active before and after func
execution. This effectively
creates a pause/suspend point for the job and prevents returning a result or performing an action on a result if the job has been completed/cancelled.
Note: This should only be used inside of a JobFunc
.
async delay(milliseconds: number): Promise<void>
Delays a job for the specified amount of time and checks for cancellation before and after the delay.
cancel(reason?: JobCancellationException)
Cancels the current job and all children jobs.
cancelChildren(reason?: JobCancellationException)
Cancels all children jobs without cancelling the current job.
class SupervisorJob extends Job<void>
A helper extension of Job
that never completes until it is cancelled. This effectively provides a long-running context to launch children jobs in.
export type JobFunc<T> = (job: JobHandle) => Promise<Outcome<T>>
The block of work a Job
executes. The job
parameter is a handle of the job's instance to allow launching of new jobs or pausing the job.
interface JobHandle {
isActive: boolean
isCompleted: boolean
isCancelled: boolean
childCount: number
ensureActive(): void
launch<R>(func: JobFunc<R>): Job<R>
launchAndRun<R>(func: JobFunc<R>): Promise<Outcome<R>>
pause<R>(func: Promise<R>): Promise<R>
delay(milliseconds: number): Promise<void>
cancel(reason?: JobCancellationException): void
cancelChildren(reason?: JobCancellationException): void
}
A handle for the current job used in JobFunc
. This interface is equivalent to Job
's interface with the exception of run
and runWithTimeout
to prevent recursive running of the Job
inside its JobFunc
.
export class JobCancellationException implements Error {
name: string = "JobCancellationException"
message: string = `${this.reason}`
constructor(public reason: JobCancellationReason) {}
}
Thrown when a job or its parent is cancelled or if a job is run more than once.
export enum JobCancellationReason {
ParentJobCancelled,
ParentJobCompleted,
JobCancelled,
JobCompleted,
}
The reason a job was cancelled.
ParentJobCancelled
: The parent job was cancelled
ParentJobCompleted
: The parent job completed
JobCancelled
: The current job was cancelled
JobCompleted
: The current job was already completed. This only happens if the same job is run more than once.