Previous: TypeScript
Next: Advanced
By default, ember-concurrency tasks run concurrently
— if you call myTask.perform(); myTask.perform();
,
two instances of the task will run at the same time (unless the object
they live on is destroyed, in which case they'll be canceled).
Often, you want to guarantee that no more than one instance of a task runs at the same time; for instance, if you have a task that saves model state to the server, you probably don't want that task to run concurrently — you want it to run sequentially, or you might want to ignore attempts to perform the task if it's already running. Manually enforcing these constraints is tricky and often results in redundant, error-prone boilerplate, but ember-concurrency makes it easy to rein in this undesired concurrency with the modifiers described below.
All of the examples below run the same task function (which just pauses for a moment and then completes), but with different task modifiers applied:
export default class SharedTasksController extends Controller { @task defaultTask = SHARED_TASK_FN; @task({ restartable: true }) restartableTask = SHARED_TASK_FN; @task({ enqueue: true }) enqueuedTask = SHARED_TASK_FN; @task({ drop: true }) droppingTask = SHARED_TASK_FN; @task({ keepLatest: true }) keepLatestTask = SHARED_TASK_FN; }
Tap the task.perform()
button a few times. Note how
the lifetimes of each task overlap, and each task runs to completion.
The restartable
modifier ensures that only one instance
of a task is running by canceling any currently-running tasks and starting
a new task instance immediately. Note how there is no task overlap,
and how currently running tasks get canceled
if a new task starts before a prior one completes.
Check out Debounced Auto-Search for a practical example of restartable
The enqueue
modifier ensures that only one instance
of a task is running by maintaining a queue of pending tasks and
running them sequentially. Note how there is no task overlap, but no
tasks are canceled either.
The drop
modifier drops tasks that are .perform()
ed
while another is already running. Dropped tasks' functions are never even called.
Check out the Loading UI example for a common
use case for drop
The keepLatest
will drop all but the most recent intermediate .perform()
,
which is enqueued to run later.
Use case: you poll the server in a loop, but during the server request, you get some other indication (say, via websockets) that the data is stale and you need to query the server again when the initial request completed.
Previous: TypeScript
Next: Advanced