Vue Concurrency Manager

6.0.0-0 · active · verified Sun Apr 19

vue-concurrency is a JavaScript library designed for encapsulating asynchronous operations and managing concurrency within Vue.js applications, leveraging the Composition API. Inspired by `ember-concurrency`, it provides a robust abstraction layer to reduce boilerplate associated with complex async flows. The current active version is `6.0.0-0` (a pre-release) which introduces features like global configuration and pruning, while the `5.x` series provides stable support for Vue 3.3+. Earlier versions (4.x) support Vue 2.7 and 3.2. Key differentiators include built-in TypeScript support, sophisticated async cancellation mechanisms via generator functions and the CAF library, and the ability to provide `AbortSignal` for native fetch/XHR abortion. It offers a reactive derived state (e.g., `isRunning`, `isIdle`, `isFinished`) for tracking operation status and powerful concurrency management strategies such as `drop()`, `restartable()`, and `enqueue()`. The library is actively maintained with regular updates and experimental SSR support.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates how to create an asynchronous task for an autocomplete search, manage its loading state (`isRunning`), and apply the `drop` concurrency strategy using Vue 3's Composition API and `vue-concurrency`.

import { defineComponent, ref } from 'vue';
import { useTask } from 'vue-concurrency';

export default defineComponent({
  setup() {
    const searchTerm = ref('');
    const searchResults = ref<string[]>([]);
    const error = ref<string | null>(null);

    // Define an asynchronous task for searching
    const searchTask = useTask(function* (term: string) {
      error.value = null;
      searchResults.value = [];
      if (!term) {
        return;
      }
      try {
        // Simulate an API call with a delay. `yield` makes it cancellable.
        yield new Promise(resolve => setTimeout(resolve, 500));

        // Simulate a potential network error
        if (Math.random() < 0.2) {
          throw new Error('Simulated network error!');
        }

        const results = Array.from({ length: 3 }, (_, i) => `${term} result ${i + 1}`);
        searchResults.value = results;
      } catch (e: any) {
        error.value = e.message;
      }
    }).drop(); // Concurrency strategy: if a new search starts, previous one is cancelled/dropped

    const onSearchInput = (event: Event) => {
      const input = event.target as HTMLInputElement;
      searchTerm.value = input.value;
      // Perform the task whenever the input changes
      searchTask.perform(input.value);
    };

    return {
      searchTerm,
      searchResults,
      error,
      searchTask,
      onSearchInput
    };
  },
  template: `
    <div style="padding: 20px; font-family: sans-serif;">
      <h1>Autocomplete Search</h1>
      <input
        type="text"
        v-model="searchTerm"
        @input="onSearchInput"
        placeholder="Type to search..."
        style="padding: 8px; font-size: 16px; width: 300px;"
      />
      <div v-if="searchTask.isRunning" style="margin-top: 10px; color: gray;">Searching...</div>
      <div v-if="error" style="margin-top: 10px; color: red; font-weight: bold;">Error: {{ error }}</div>
      <ul v-if="searchResults.length && !searchTask.isRunning" style="list-style: none; padding: 0; margin-top: 10px;">
        <li v-for="result in searchResults" :key="result" style="padding: 5px 0; border-bottom: 1px solid #eee;">{{ result }}</li>
      </ul>
      <div v-if="!searchTerm && !searchTask.isRunning && !error" style="margin-top: 10px; color: #aaa;">Start typing to see results</div>
    </div>
  `
});

view raw JSON →