ember-concurrency

repository·master·Indexed 20 days ago

https://github.com/machty/ember-concurrency

A library providing improved concurrency primitives for Ember.js to manage asynchronous tasks. It features cancelable and restartable tasks that automatically clean up when their host object is destroyed. The library includes task modifiers like restartable(), enqueue(), and drop() to control concurrency, as well as cancellation-aware utilities for Promise-like operations and specialized yieldable utilities such as timeout() and animationFrame(). Version 4.0.0-beta.2 requires a Babel transform for async-arrow task syntax.

Tokens
6.9K
Snippets
25
Records
40
Agent score
71%

What's inside ember-concurrency

  1. Use Task Modifiers to control task execution

    master

    Task Modifiers are a specific ember-concurrency concept used to define how a task behaves when it is invoked while already running. Common modifiers include:

    • restartable: Restarts the task from the beginning.
    • enqueue: Queues the next execution to run after the current one finishes.
    • drop: Drops the new invocation if the task is already running.
    • keepLatest: Drops the current running task and starts the new one (similar to restartable but specifically manages the latest invocation).
    • maxConcurrency: Limits how many instances of the task can run at once.
  2. Configure the Babel Transform for async-arrow tasks

    master

    Ember Concurrency requires a Babel Transform to convert tasks written in the "async-arrow" notation (e.g., fooTask = task(async () => { /*...*/ })) into generator functions.

    Because Ember Concurrency 4.0.0+ is an Embroider V2 Addon, you must configure this transform in your consuming application or addon depending on your project type.

    // For an Ember Application (ember-cli-build.js)
    const app = new EmberApp(defaults, {
      // ...
      babel: {
        plugins: [
          // ... any other plugins
          require.resolve("ember-concurrency/async-arrow-task-transform"),
    
          // NOTE: put any code coverage plugins last, after the transform.
        ],
      }
    });
    
    // For a V1 Addon (index.js)
    // ...
    options: {
      babel: {
        plugins: [
          require.resolve('ember-concurrency/async-arrow-task-transform'),
        ],
      },
    },
    
    // For a V2 Addon (babel.config.json)
    {
      "plugins": [
        [
          // ... any other plugins
          "ember-concurrency/async-arrow-task-transform"
        ]
      ]
    }
  3. Set up the test-app development environment

    master

    To work on the test-app application, ensure you have Git, Node.js (with npm), Ember CLI, and Google Chrome installed. Follow these steps to clone and install dependencies:

    1. Clone the repository.
    2. Navigate to the test-app directory.
    3. Run npm install to install dependencies.
    git clone <repository-url>
    cd test-app
    npm install
  4. Compatibility requirements for `ember-concurrency` 2.0

    master

    Supported Versions

    • Ember: 3.8 LTS and up.
    • Node: Support for Node 8 has been dropped.

    Ember 3.16+ and @tracked

    On Ember 3.16+, ember-concurrency uses @tracked properties internally. This allows Tasks and TaskInstances to work seamlessly with Glimmer components.

    Note for Classic Ember users: If you read Task or TaskInstance state via native getters inside a computed property, you may need to annotate that native getter with @dependentKeyCompat to ensure changes are visible to the computed property system. This also applies to decorators like @lastValue.

  5. How to support both ember-concurrency 1.x and 2.x in addons

    master

    If you are an addon maintainer needing to support both ember-concurrency 1.x and 2.x, follow these guidelines:

    1. Decorators: Do not use the built-in decorators in 2.x if you need 1.x compatibility. Instead, continue using ember-concurrency-decorators@^2.0.3 or higher.
    2. Dependency Specifiers: Use a version range in your package.json to allow both major versions.
    3. Accessing State: For Ember versions < 3.1, do not use .get() directly on Task, TaskGroup, or TaskInstance. Instead, use Ember.get(task, 'state') to ensure compatibility across both ember-concurrency versions.
    4. Testing: Use ember-try scenarios to test against both versions to prevent regressions.
    // package.json dependency configuration
    {
        "dependencies": {
          "ember-concurrency": "^1.0.0 || ^2.0.0-rc.1"
        }
    }
    
    // config/ember-try.js configuration
    {
      "name": "ember-concurrency-1.x",
      "npm": {
        "dependencies": {
          "ember-concurrency": "^1.3.0"
        }
      }
    },
    {
      "name": "ember-concurrency-2.x",
      "npm": {
        "dependencies": {
          "ember-concurrency": "^2.0.0-rc.1"
        }
      }
    }
  6. Import and use ember-concurrency basics

    master

    The core functionality of ember-concurrency is available via the ember-concurrency module. Most common use cases involve importing task to define asynchronous tasks and timeout to introduce delays within those tasks. Tasks are defined using generator functions (indicated by the * syntax) and use yield to await asynchronous operations like timeout.

    import Component from '@glimmer/component';
    import { tracked } from '@glimmer/tracking';
    import { task, timeout } from 'ember-concurrency';
    
    export default class MyComponent extends Component {
      @tracked num;
    
      constructor() {
        super(...arguments);
        this.loopingTask.perform();
      }
    
      @task *loopingTask() {
        while (true) {
          this.num = Math.random();
          yield timeout(100);
        }
      }
    });
  7. Migrate from `ember-concurrency-decorators` to `ember-concurrency`

    master

    In ember-concurrency 2.0, the decorators previously provided by the ember-concurrency-decorators addon are now built directly into the core package. To migrate, replace your imports from the old addon with imports from ember-concurrency.

    Note: The 'ugly' decorator syntax (e.g., @(task(function* () { ... }).drop())) remains available for compatibility with computed-based TaskProperty implementations but is deprecated.

    - import { restartableTask, task } from 'ember-concurrency-decorators';
    + import { restartableTask, task } from 'ember-concurrency';