AwaitQueue

3.3.0 · active · verified Sun Apr 19

AwaitQueue is a TypeScript-first utility designed to manage and execute asynchronous tasks sequentially within Node.js and browser environments. Currently stable at version 3.3.0, it provides a robust mechanism to enqueue `Promise`-returning or async functions, ensuring they run one after another, preventing concurrency issues. Key features include task naming, the ability to remove specific pending tasks, and a `stop` mechanism that rejects all currently pending tasks with custom error types. Its primary differentiator lies in its straightforward API for controlling task flow, particularly useful in scenarios requiring strict ordering, such as database writes, API calls with rate limits, or resource-intensive operations.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates the creation and usage of AwaitQueue, enqueuing multiple asynchronous tasks, and handling task removal and queue stoppage with specific error types. It shows how tasks run sequentially and how to react to their outcomes.

import { AwaitQueue, AwaitQueueStoppedError, AwaitQueueRemovedTaskError } from 'awaitqueue';

async function runTasks() {
  const queue = new AwaitQueue();
  console.log('Queue created. Size:', queue.size);

  // Task 1: A simple resolving task
  queue.push(async () => {
    console.log('Task 1: Starting (2s)');
    await new Promise(resolve => setTimeout(resolve, 2000));
    console.log('Task 1: Completed');
    return 'Result 1';
  }, 'task-one').then(res => console.log(`Task 1 resolved with: ${res}`)).catch(err => console.error(`Task 1 failed: ${err.message}`));

  // Task 2: A task that takes longer
  queue.push(async () => {
    console.log('Task 2: Starting (5s)');
    await new Promise(resolve => setTimeout(resolve, 5000));
    console.log('Task 2: Completed');
    return 'Result 2';
  }, 'task-two').then(res => console.log(`Task 2 resolved with: ${res}`)).catch(err => console.error(`Task 2 failed: ${err.message}`));

  // Task 3: A task to be removed
  const task3Promise = queue.push(async () => {
    console.log('Task 3: Should not run');
    return 'Result 3';
  }, 'task-three');
  task3Promise.then(res => console.log(`Task 3 resolved with: ${res}`)).catch(err => {
    if (err instanceof AwaitQueueRemovedTaskError) {
      console.warn(`Task 3 was removed: ${err.message}`);
    } else {
      console.error(`Task 3 failed: ${err.message}`);
    }
  });

  // Task 4: A task to be stopped (after Task 2, but before its completion)
  const task4Promise = queue.push(async () => {
    console.log('Task 4: Should be stopped');
    await new Promise(resolve => setTimeout(resolve, 1000));
    return 'Result 4';
  }, 'task-four');
  task4Promise.then(res => console.log(`Task 4 resolved with: ${res}`)).catch(err => {
    if (err instanceof AwaitQueueStoppedError) {
      console.warn(`Task 4 was stopped: ${err.message}`);
    } else {
      console.error(`Task 4 failed: ${err.message}`);
    }
  });

  console.log('Initial queue size:', queue.size);
  console.log('Dumping queue:', queue.dump());

  // Simulate actions after some time
  await new Promise(resolve => setTimeout(resolve, 3000)); // Wait for Task 1 to finish and Task 2 to start

  console.log('Removing Task 3 (index 1 in 0-indexed dump after Task 1 ran)');
  queue.remove(1); // Task 3 is at index 1 after Task 1 finishes and Task 2 is at index 0

  await new Promise(resolve => setTimeout(resolve, 2000)); // Wait a bit more

  console.log('Stopping the queue. All remaining pending tasks will be rejected.');
  queue.stop();

  console.log('Final queue size:', queue.size);
  console.log('Dumping queue after stop:', queue.dump());
}

runTasks().catch(console.error);

view raw JSON →