The TaskController interface of the Prioritized Task Scheduling API represents a controller object that can be used to both abort and change the priority of one or more prioritized tasks. If there is no need to change task priorities, then AbortController can be used instead.

A new TaskController instance is created using the TaskController() constructor, optionally specifying a priority for its associated signal (a TaskSignal). If not specified, the signal will have a priority of "user-visible" by default.

The controller's signal can be passed as an argument to the Scheduler.postTask() method for one or more tasks. For mutable tasks (only) the task is initialized with the signal priority, and can later be changed by calling TaskController.setPriority(). For immutable tasks, any priority initialized or set by the controller is ignored.

Tasks can be aborted by calling abort() on the controller.

AbortController TaskController



Creates a new TaskController object, optionally specifying the priority of its associated signal.

Instance methods

This interface also inherits the methods of its parent, AbortController.


Sets the priority of the controller's signal, and hence the priority of any tasks with which it is associated. This notifies observers of the priority change by dispatching a prioritychange event.

Instance properties

This interface also inherits the properties of its parent, AbortController.

TaskController.signal Read only

Returns a TaskSignal object instance. The signal is passed to tasks so that they can be aborted or re-prioritized by the controller. The property is inherited from AbortController.


Note: Additional "live" examples can be found in: Prioritized Task Scheduling API > Examples.

First we create a task controller, setting the priority of its associated signal to user-blocking.

// Create a TaskController, setting its signal priority to 'user-blocking'
const controller = new TaskController({priority: 'user-blocking'});

We then add an event listener for prioritychange events (here addEventListener() is called, but we could instead assign a handler to TaskSignal.onprioritychange). The handler uses previousPolicy on the event to get the original priority and TaskSignal.priority on the event target to get the new priority.

// Listen for 'prioritychange' events on the controller's signal.
controller.signal.addEventListener('prioritychange', (event) => {
  const previousPriority = event.previousPriority;
  const newPriority = event.target.priority;
  console.log(`Priority changed from ${previousPriority} to ${newPriority}.`);

We can also listen for abort events as shown below. This same approach would be used if the controller was an AbortController.

controller.signal.addEventListener('abort', (event) => {
  console.log('Task aborted');

Next we post the task, passing the controller signal in the optional argument. In this case the task is just an arrow function that resolves the promise by returning some text. We use then and catch to handle when the task resolves or is rejected, logging the return text or the error in each case. Note that in a later code block we abort the task, so only the catch() block will actually be run!

// Post task using the controller's signal.
// The signal priority sets the initial priority of the task
scheduler.postTask(() => 'Task execute', {signal: controller.signal})
  .then((taskResult) => { console.log(`${taskResult}`); }) // Aborted (won't run)
  .catch((error) => { console.log(`Catch error: ${error}`); });  // Log error

We can use the controller to manage the task. Here we can change the priority using TaskController.setPriority(). This will trigger the associated prioritychange event.

// Change the priority to 'background' using the controller

Finally, the task can be aborted by calling abort() on the controller.

// Abort the task

The console output of this example would be:

The priority changed from user-blocking to background.
Task aborted
Catch error: AbortError


Prioritized Task Scheduling
# sec-task-controller

Browser compatibility

BCD tables only load in the browser