Previous: TypeScript / Glint
Next: Using maxConcurrency
Previous versions of Ember Concurrency recommended decorators-based APIs for declaring tasks, but these APIs are no longer recommended due to decorators not playing nicely with TypeScript-based APIs.
If you would like to see the older APIs, please check out the old docs site.
See this link.
In general, yes, but they're not officially supported or tested on, so
your mileage may vary. The
ES6 Generator Function syntax
that ember-concurrency relies on can be automatically transpiled using
Babel and
regenerator. You may
need to experiment with your
config/targets.js
and/or ember-cli-babel settings to include the regenerator runtime and
proper transpilation for your needs.
Async functions are just syntax sugar for Promises. Promises aren't cancelable, and as of November 2020, there is no active TC39 specification under development for adding cancelation to promises. Tasks, in contrast, are cancelable.
The design of Promises is such that once a Promise has been created, it's not possible to externally reach in and resolve/reject a Promise. This constraint encourages a clear, unidirectional, structured architecture for building asynchronous chains of logic.
Like Promises, the return/reject value of an EC Task cannot be externally
set / overridden; in other words, once a Task has been performed, there's
no way to externally force it to return/reject early, with the exception
of cancelation. When you
.cancel()
a task instance, the task will "return" from wherever it is currently
paused (e.g. at a
await
). Presently, there is no API to "delay" the cancelation
of a Task once a cancel has been requested, but this functionality might
be added to future APIs.
.dispose()
(though this approach is frowned up in favor of explicitly specifying
when an observable should terminate -- e.g. via
takeUntil()
).
Tasks can be canceled
implicitly (via 1. host object destruction, 2. the
restartable
task modifier) or explicitly (via
.cancel() / .cancelAll()
), though, like Observables, the
implicit approach is preferable.
.set()
values on the object the task lives on so that those values can be
easily displayed in the template. Tasks also expose the value / error
returned from the task function (see
Derived State), which are
preferable to
.set()
s where possible.
.isIdle / .isRunning / .numRunning
) and 3) it's often
easier to model domain state as bindable values rather than discrete
events.
Previous: TypeScript / Glint
Next: Using maxConcurrency