Global

Members

(constant) all

A cancelation-aware variant of Promise.all. The normal version of a Promise.all just returns a regular, uncancelable Promise. The ember-concurrency variant of all() has the following additional behavior:

  • if the task that yielded all() is canceled, any of the TaskInstances passed in to all will be canceled
  • if any of the TaskInstances (or regular promises) passed in reject (or are canceled), all of the other unfinished TaskInstances will be automatically canceled.

Check out the "Awaiting Multiple Child Tasks example"

Source:

(constant) allSettled

A cancelation-aware variant of RSVP.allSettled. The normal version of a RSVP.allSettled just returns a regular, uncancelable Promise. The ember-concurrency variant of allSettled() has the following additional behavior:

  • if the task that yielded allSettled() is canceled, any of the TaskInstances passed in to allSettled will be canceled
Source:

(constant) forever

Yielding forever will pause a task indefinitely until it is cancelled (i.e. via host object destruction, the restartable modifier, or manual cancellation).

This is often useful in cases involving animation: if you're using Liquid Fire, or some other animation scheme, sometimes you'll notice buttons visibly reverting to their inactive states during a route transition. By yielding forever in a Component task that drives a button's active state, you can keep a task indefinitely running until the animation runs to completion.

NOTE: Liquid Fire also includes a useful waitUntilIdle() method on the liquid-fire-transitions service that you can use in a lot of these cases, but it won't cover cases of asynchrony that are unrelated to animation, in which case forever might be better suited to your needs.

import { task, forever } from 'ember-concurrency';
export default class MyComponent extends Component {
  @service myService;
  @task *myTask() {
    yield this.myService.doSomethingThatCausesATransition();
    yield forever;
  }
}
Source:

(constant) hash

A cancelation-aware variant of RSVP.hash. The normal version of a RSVP.hash just returns a regular, uncancelable Promise. The ember-concurrency variant of hash() has the following additional behavior:

  • if the task that yielded hash() is canceled, any of the TaskInstances passed in to hash will be canceled
  • if any of the items rejects/cancels, all other cancelable items (e.g. TaskInstances) will be canceled
Source:

(constant) hashSettled

A cancelation-aware variant of RSVP.hashSettled. The normal version of a RSVP.hashSettled just returns a regular, uncancelable Promise. The ember-concurrency variant of hashSettled() has the following additional behavior:

  • if the task that yielded hashSettled() is canceled, any of the TaskInstances passed in to hashSettled will be canceled
Source:

(constant) race

A cancelation-aware variant of Promise.race. The normal version of a Promise.race just returns a regular, uncancelable Promise. The ember-concurrency variant of race() has the following additional behavior:

  • if the task that yielded race() is canceled, any of the TaskInstances passed in to race will be canceled
  • once any of the tasks/promises passed in complete (either success, failure, or cancelation), any of the TaskInstances passed in will be canceled

Check out the "Awaiting Multiple Child Tasks example"

Source:

Methods

animationFrame()

Yielding animationFrame() will pause a task until after the next animation frame using the native requestAnimationFrame() browser API.

The task below, when performed, will print the time since the last loop run for every animation frame.

export default class MyComponent extends Component {
  @task *myTask() {
    let lastNow = performance.now();
    while (true) {
      yield animationFrame();

      let now = performance.now();
      let dt = now - lastNow;
      lastNow = now;

      console.log(dt);
    }
  }
}
Source:

didCancel(error) → {boolean}

Returns true if the object passed to it is a TaskCancelation error. If you call someTask.perform().catch(...) or otherwise treat a TaskInstance like a promise, you may need to handle the cancelation of a TaskInstance differently from other kinds of errors it might throw, and you can use this convenience function to distinguish cancelation from errors.

click() {
  this.myTask.perform().catch(e => {
    if (!didCancel(e)) { throw e; }
  });
}
Parameters:
Name Type Description
error object

the caught error, which might be a TaskCancelation

Source:
Returns:
Type
boolean

dropTask(optionsopt, nullable) → {Task}

Turns the decorated generator function into a task and applies the drop modifier.

Optionally takes a hash of options that will be applied as modifiers to the task. For instance maxConcurrency, on, or group.

You can also define an Encapsulated Task by decorating an object that defines a perform generator method.

import Component from '@ember/component';
import { task, dropTask } from 'ember-concurrency';

class MyComponent extends Component {
  @task
  *plainTask() {}

  @dropTask({ cancelOn: 'click' })
  *myDropTask() {}
}
Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task modifier options. See task for list.

Source:
Returns:
Type
Task

dropTaskGroup(optionsopt, nullable) → {TaskGroup}

Turns the decorated property into a task group and applies the drop modifier.

Optionally takes a hash of further options that will be applied as modifiers to the task group.

Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task group modifier options. See task for list.

Source:
Returns:
Type
TaskGroup

enqueueTask(optionsopt, nullable) → {Task}

Turns the decorated generator function into a task and applies the enqueue modifier.

Optionally takes a hash of options that will be applied as modifiers to the task. For instance maxConcurrency, on, or group.

You can also define an Encapsulated Task by decorating an object that defines a perform generator method.

import Component from '@ember/component';
import { task, enqueueTask } from 'ember-concurrency';

class MyComponent extends Component {
  @task
  *plainTask() {}

  @enqueueTask({ cancelOn: 'click' })
  *myEnqueueTask() {}
}
Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task modifier options. See task for list.

Source:
Returns:
Type
Task

enqueueTaskGroup(optionsopt, nullable) → {TaskGroup}

Turns the decorated property into a task group and applies the enqueue modifier.

Optionally takes a hash of further options that will be applied as modifiers to the task group.

Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task group modifier options. See task for list.

Source:
Returns:
Type
TaskGroup

getModifier(name) → (nullable) {TaskFactory~TaskModifier}

Returns a specified modifier, if it exists in the registry

Parameters:
Name Type Description
name string

Name of the modifier

Source:
Returns:
Type
TaskFactory~TaskModifier

hasModifier(name) → {boolean}

Returns whether a specified modifier exists in the registry

Parameters:
Name Type Description
name string

Name of the modifier

Source:
Returns:
Type
boolean

keepLatestTask(optionsopt, nullable) → {Task}

Turns the decorated generator function into a task and applies the keepLatest modifier.

Optionally takes a hash of options that will be applied as modifiers to the task. For instance maxConcurrency, on, or group.

You can also define an Encapsulated Task by decorating an object that defines a perform generator method.

import Component from '@ember/component';
import { task, keepLatestTask } from 'ember-concurrency';

class MyComponent extends Component {
  @task
  *plainTask() {}

  @keepLatestTask({ cancelOn: 'click' })
  *myKeepLatestTask() {}
}
Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task modifier options. See task for list.

Source:
Returns:
Type
Task

keepLatestTaskGroup(optionsopt, nullable) → {TaskGroup}

Turns the decorated property into a task group and applies the keepLatest modifier.

Optionally takes a hash of further options that will be applied as modifiers to the task group.

Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task group modifier options. See task for list.

Source:
Returns:
Type
TaskGroup

rawTimeout(ms)

Yielding rawTimeout(ms) will pause a task for the duration of time passed in, in milliseconds.

The timeout will use the native setTimeout() browser API, instead of the Ember runloop, which means that test helpers will not wait for it to complete.

The task below, when performed, will print a message to the console every second.

export default class MyComponent extends Component {
  @task *myTask() {
    while (true) {
      console.log("Hello!");
      yield rawTimeout(1000);
    }
  }
}
Parameters:
Name Type Description
ms number

the amount of time to sleep before resuming the task, in milliseconds

Source:

registerModifier(name, callback)

Registers a new modifier with the modifier registry

Parameters:
Name Type Description
name string

Name of the modifier

callback TaskFactory~TaskModifier
Source:

restartableTask(optionsopt, nullable) → {Task}

Turns the decorated generator function into a task and applies the restartable modifier.

Optionally takes a hash of options that will be applied as modifiers to the task. For instance maxConcurrency, on, or group.

You can also define an Encapsulated Task by decorating an object that defines a perform generator method.

import Component from '@ember/component';
import { task, restartableTask } from 'ember-concurrency';

class MyComponent extends Component {
  @task
  *plainTask() {}

  @restartableTask({ cancelOn: 'click' })
  *myRestartableTask() {}
}
Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task modifier options. See task for list.

Source:
Returns:
Type
Task

restartableTaskGroup(optionsopt, nullable) → {TaskGroup}

Turns the decorated property into a task group and applies the restartable modifier.

Optionally takes a hash of further options that will be applied as modifiers to the task group.

Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task group modifier options. See task for list.

Source:
Returns:
Type
TaskGroup

task(optionsopt, nullable) → {Task}

A Task is a cancelable, restartable, asynchronous operation that is driven by a generator function. Tasks are automatically canceled when the object they live on is destroyed (e.g. a Component is unrendered).

Turns the decorated generator function into a task.

Optionally takes a hash of options that will be applied as modifiers to the task. For instance maxConcurrency, on, group or keepLatest.

By default, tasks have no concurrency constraints (multiple instances of a task can be running at the same time) but much of a power of tasks lies in proper usage of Task Modifiers that you can apply to a task.

You can also define an Encapsulated Task by decorating an object that defines a perform generator method.

import Component from '@ember/component';
import { task } from 'ember-concurrency';

class MyComponent extends Component {
  @task
  *plainTask() {}

  @task({ maxConcurrency: 5, keepLatest: true, cancelOn: 'click' })
  *taskWithModifiers() {}
}
Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task modifier options

Properties
Name Type Attributes Description
cancelOn string | Array.<string> <optional>

Events to cancel task on. Applies only to &#64;ember/component

enqueue boolean <optional>

Sets enqueue modifier on task if true

evented boolean <optional>

Enables task lifecycle events for this Task, if true

debug boolean <optional>

Enables task debugging if true

drop boolean <optional>

Sets drop modifier on task if true

group string <optional>

Associates task with the group specified

keepLatest boolean <optional>

Sets keepLatest modifier on task if true

maxConcurrency number <optional>

Sets the maximum number of running task instances for the task

observes string | Array.<string> <optional>

Properties to watch and cause task to be performed when they change

on string | Array.<string> <optional>

Events to perform task on. Applies only to &#64;ember/component

onState function <optional>
<nullable>

Callback to use for state tracking. May be set to null to disable state tracking.

restartable boolean <optional>

Sets restartable modifier on task if true

Source:
Returns:
Type
Task

task(generatorFunction) → {TaskProperty}

TODO: update docs to reflect both old and new ES6 styles

A Task is a cancelable, restartable, asynchronous operation that is driven by a generator function. Tasks are automatically canceled when the object they live on is destroyed (e.g. a Component is unrendered).

To define a task, use the task(...) function, and pass in a generator function, which will be invoked when the task is performed. The reason generator functions are used is that they (like the proposed ES7 async-await syntax) can be used to elegantly express asynchronous, cancelable operations.

You can also define an Encapsulated Task by passing in an object that defined a perform generator function property.

The following Component defines a task called myTask that, when performed, prints a message to the console, sleeps for 1 second, prints a final message to the console, and then completes.

import { task, timeout } from 'ember-concurrency';
export default Component.extend({
  myTask: task(function * () {
    console.log("Pausing for a second...");
    yield timeout(1000);
    console.log("Done!");
  })
});
<button {{action myTask.perform}}>Perform Task</button>

By default, tasks have no concurrency constraints (multiple instances of a task can be running at the same time) but much of a power of tasks lies in proper usage of Task Modifiers that you can apply to a task.

Parameters:
Name Type Description
generatorFunction function

the generator function backing the task.

Source:
Returns:
Type
TaskProperty

taskGroup(optionsopt, nullable) → {TaskGroup}

"Task Groups" provide a means for applying task modifiers to groups of tasks. Once a Task is declared as part of a group task, modifiers like drop or restartable will no longer affect the individual Task. Instead those modifiers can be applied to the entire group.

Turns the decorated property into a task group.

Optionally takes a hash of options that will be applied as modifiers to the task group. For instance maxConcurrency or keepLatest.

import Component from '@glimmer/component';
import { task, taskGroup } from 'ember-concurrency';

class MyComponent extends Component {
  @taskGroup({ maxConcurrency: 5 }) chores;

  @task({ group: 'chores' })
  *mowLawn() {}

  @task({ group: 'chores' })
  *doDishes() {}
}
Parameters:
Name Type Attributes Default Description
options object <optional>
<nullable>
{}

Task group modifier options. See task for list.

Source:
Returns:
Type
TaskGroup

taskGroup() → {TaskGroup}

"Task Groups" provide a means for applying task modifiers to groups of tasks. Once a Task is declared as part of a group task, modifiers like drop or restartable will no longer affect the individual Task. Instead those modifiers can be applied to the entire group.

import { task, taskGroup } from 'ember-concurrency';

export default class MyController extends Controller {
  @taskGroup({ drop: true }) chores;

  @task({ group: 'chores' }) mowLawn = taskFn;
  @task({ group: 'chores' }) doDishes = taskFn;
  @task({ group: 'chores' }) changeDiapers = taskFn;
}
Source:
Returns:
Type
TaskGroup

timeout(ms)

Yielding timeout(ms) will pause a task for the duration of time passed in, in milliseconds.

This timeout will be scheduled on the Ember runloop, which means that test helpers will wait for it to complete before continuing with the test. See rawTimeout() if you need different behavior.

The task below, when performed, will print a message to the console every second.

export default class MyComponent extends Component {
  @task *myTask() {
    while (true) {
      console.log("Hello!");
      yield timeout(1000);
    }
  }
}
Parameters:
Name Type Description
ms number

the amount of time to sleep before resuming the task, in milliseconds

Source:

waitForEvent(object, eventName)

Use waitForEvent to pause the task until an event is fired. The event can either be a jQuery event or an Ember.Evented event (or any event system where the object supports .on() .one() and .off()).

import { task, waitForEvent } from 'ember-concurrency';
export default class MyComponent extends Component {
  @task *myTask() {
    console.log("Please click anywhere..");
    let clickEvent = yield waitForEvent($('body'), 'click');
    console.log("Got event", clickEvent);

    let emberEvent = yield waitForEvent(this, 'foo');
    console.log("Got foo event", emberEvent);

    // somewhere else: component.trigger('foo', { value: 123 });
  }
}
Parameters:
Name Type Description
object object

the Ember Object, jQuery element, or other object with .on() and .off() APIs that the event fires from

eventName function

the name of the event to wait for

Source:

waitForProperty(object, key, callbackOrValue)

Use waitForProperty to pause the task until a property on an object changes to some expected value. This can be used for a variety of use cases, including synchronizing with another task by waiting for it to become idle, or change state in some other way. If you omit the callback, waitForProperty will resume execution when the observed property becomes truthy. If you provide a callback, it'll be called immediately with the observed property's current value, and multiple times thereafter whenever the property changes, until you return a truthy value from the callback, or the current task is canceled. You can also pass in a non-Function value in place of the callback, in which case the task will continue executing when the property's value becomes the value that you passed in.

import { task, waitForProperty } from 'ember-concurrency';
export default class MyComponent extends Component {
  @tracked foo = 0;

  @task *myTask() {
    console.log("Waiting for `foo` to become 5");

    yield waitForProperty(this, 'foo', v => v === 5);
    // alternatively: yield waitForProperty(this, 'foo', 5);

    // somewhere else: this.foo = 5;

    console.log("`foo` is 5!");

    // wait for another task to be idle before running:
    yield waitForProperty(this, 'otherTask.isIdle');
    console.log("otherTask is idle!");
  }
}
Parameters:
Name Type Description
object object

an object (most likely an Ember Object)

key string

the property name that is observed for changes

callbackOrValue function

a Function that should return a truthy value when the task should continue executing, or a non-Function value that the watched property needs to equal before the task will continue running

Source:

waitForQueue(queueName)

Use waitForQueue to pause the task until a certain run loop queue is reached.

import { task, waitForQueue } from 'ember-concurrency';
export default class MyComponent extends Component {
  @task *myTask() {
    yield waitForQueue('afterRender');
    console.log("now we're in the afterRender queue");
  }
}
Parameters:
Name Type Description
queueName string

the name of the Ember run loop queue

Source: