Package Exports
- ember-concurrency-decorators
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (ember-concurrency-decorators) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
ember-concurrency-decorators
This Ember addon lets you use the decorator syntax for declaring/configuring ember-concurrency tasks.
Installation
You'll need at least ember-cli@2.13+ and ember-cli-babel@6+.
Then install as any other addon:
ember install ember-concurrency-decoratorsIf you are not using TypeScript, in order for ember-cli-babel to understand the @decorator syntax, you at least also need to install @ember-decorators/babel-transforms. Instead of that you can also install the ember-decorators meta package:
ember install ember-decorators
# or
ember install @ember-decorators/babel-transformsYou need at least @ember-decorators/babel-transforms@^3.1.0. If you are stuck
on v2.1.2, use ember-concurrency-decorators@0.3.0.
Usage
Available decorators
@task: turns a generator method into a task@restartableTask@dropTask@keepLatestTask@enqueueTask
@taskGroup: creates a task group from a property@restartableTaskGroup@dropTaskGroup@keepLatestTaskGroup@enqueueTaskGroup
@lastValue: alias a property to the result of a task with an optional default value
@task
import Component from '@ember/component';
import { task } from 'ember-concurrency-decorators';
export default class ExampleComponent extends Component {
@task
*doStuff() {
// ...
}
// and then elsewhere
executeTheTask() {
// `doStuff` is still a `Task` object that can be `.perform()`ed
this.doStuff.perform();
console.log(this.doStuff.isRunning);
}
}You can also pass further options to the task decorator:
@task({
maxConcurrency: 3,
restartable: true
})
*doStuff() {
// ...
}For your convenience, there are extra decorators for all concurrency modifiers:
| Shorthand | Equivalent |
|---|---|
@restartableTask |
@task({ restartable: true }) |
@dropTask |
@task({ drop: true }) |
@keepLatestTask |
@task({ keepLatest: true }) |
@enqueueTask |
@task({ enqueue: true }) |
You can still pass further options to these decorators, like:
@restartableTask({ maxConcurrency: 3 })
*doStuff() {
// ...
}Encapsulated Tasks
Encapsulated Tasks behave just like regular tasks, but with one crucial difference: the value of
thiswithin the task function points to the currently running TaskInstance, rather than the host object that the task lives on (e.g. a Component, Controller, etc). This allows for some nice patterns where all of the state produced/mutated by a task can be contained (encapsulated) within the Task itself, rather than having to live on the host object.
import Component from '@ember/component';
import { task } from 'ember-concurrency-decorators';
export default class ExampleComponent extends Component {
@task
doStuff = {
privateState: 123,
*perform() {
// ...
}
};
// and then elsewhere
executeTheTask() {
// `doStuff` is still a `Task` object that can be `.perform()`ed
this.doStuff.perform();
console.log(this.doStuff.isRunning);
}
}Encapulated Tasks do not work with ember-cli-typescript@1. See the
TypeScript section for more details.
@taskGroup
import Component from '@ember/component';
import { task, taskGroup } from 'ember-concurrency-decorators';
export default class ExampleComponent extends Component {
@taskGroup
someTaskGroup;
@task({ group: 'someTaskGroup' })
*doStuff() {
// ...
}
@task({ group: 'someTaskGroup' })
*doOtherStuff() {
// ...
}
// and then elsewhere
executeTheTask() {
// `doStuff` is still a `Task `object that can be `.perform()`ed
this.doStuff.perform();
// `someTaskGroup` is still a `TaskGroup` object
console.log(this.someTaskGroup.isRunning);
}
}You can also pass further options to the task group decorator:
@taskGroup({
maxConcurrency: 3,
drop: true
}) someTaskGroup;As for @task, there are extra decorators for all concurrency modifiers:
| Shorthand | Equivalent |
|---|---|
@restartableTaskGroup |
@taskGroup({ restartable: true }) |
@dropTaskGroup |
@taskGroup({ drop: true }) |
@keepLatestTaskGroup |
@taskGroup({ keepLatest: true }) |
@enqueueTaskGroup |
@taskGroup({ enqueue: true }) |
You can still pass further options to these decorators, like:
@dropTaskGroup({ maxConcurrency: 3 }) someTaskGroup;@lastValue
This decorator allows you to alias a property to the result of a task. You can also provide a default value to use before the task has completed.
import Component from '@ember/component';
import { task } from 'ember-concurrency-decorators';
import { lastValue } from 'ember-concurrency-decorators';
export default class ExampleComponent extends Component {
@task
*someTask() {
// ...
}
@lastValue('someTask')
someTaskValue;
@lastValue('someTask')
someTaskValueWithDefault = 'A default value';
}Support
JavaScript
While ember-cli-babel@6 is still supported and tested, we highly recommend that you update to ember-cli-babel@7, if you have not already.
If you are using ember-cli-babel@6, you'll need to use slightly different syntax:
import Component from '@ember/component';
import { task } from 'ember-concurrency-decorators';
export default class ExampleComponent extends Component {
@task
doStuff = function*() {
// You need to use a function assignment here, instead of the method shorthand.
};
}TypeScript
If you are using TypeScript, we highly recommend that you use at least ember-cli-typescript@^2.0.0-beta.3. Otherwise encapsulated tasks will not work.
License
This project is licensed under the MIT License.