Previous: Child Tasks
Next: Derived State
While Task Modifiers prevent a single task from running concurrently, Task Groups make it possible to prevent multiple tasks from running at the same time. Using Task Groups is a two-step process:
@taskGroup nameOfGroup;
@task({ group: ... })
to associate
the task with the group, e.g. @task({ group: 'nameOfGroup' }) *myTask() { /* ... */}
Once you define a task as part of a task group, you can no longer use
other task modifiers like drop
or restartable
on that task; instead, just apply those task modifiers to the task group property instead,
as demonstrated in the example below.
In this example, we group related "chores" tasks and by using the drop
modifier on the taskGroup
property we ensure that only one
chore task runs at a time. In addition to preventing concurrency between multiple
tasks, this example also demonstrates how having access to both the
state of the task group, as well as its individual members,
makes it very easy to build out common UI patterns, such as active/idle states
of related buttons in a button bar.
export default class TaskGroupsController extends Controller { @taskGroup({ drop: true }) chores; @task({ group: 'chores' }) mowLawn = taskFn; @task({ group: 'chores' }) doDishes = taskFn; @task({ group: 'chores' }) changeDiapers = taskFn; get tasks() { return [this.mowLawn, this.doDishes, this.changeDiapers]; } }
{{#each this.tasks as |task|}} <button class={{if task.isIdle "clickable"}} {{on "click" (perform task)}} type="button"> {{task.name}} </button> {{/each}} <h5>Chores group state: {{this.chores.state}}</h5> <h5> Most Recent Chore: {{#let this.chores.last as |taskInstance|}} {{taskInstance.task.name}} ({{taskInstance.state}}) {{/let}} </h5>
Previous: Child Tasks
Next: Derived State