Queue.js
JavaScript
progress event
event handling
asynchronous programming

Queue.js with progress event

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

When you run many asynchronous jobs through a queue, a progress event is the easiest way to tell the UI or caller how far the queue has advanced. The core idea is simple: after each task completes, emit the number of completed tasks and the total number of tasks.

Whether you are using a library named Queue.js or building your own queue wrapper, the design is the same. Progress is not magic state inside the queue. It is derived from how many tasks have finished relative to how many were scheduled.

What a Progress Event Usually Means

A useful progress payload often includes:

  • total task count
  • completed task count
  • percentage completed
  • optional current task identifier

That is enough to update a progress bar, log progress, or trigger milestones such as “50 percent done.”

A Minimal Queue With Progress Notifications

Here is a small JavaScript example that runs async tasks sequentially and emits progress updates.

javascript
1class SimpleQueue {
2  constructor() {
3    this.tasks = [];
4    this.listeners = { progress: [], done: [] };
5  }
6
7  add(task) {
8    this.tasks.push(task);
9  }
10
11  on(event, handler) {
12    this.listeners[event].push(handler);
13  }
14
15  emit(event, payload) {
16    for (const handler of this.listeners[event]) {
17      handler(payload);
18    }
19  }
20
21  async run() {
22    const total = this.tasks.length;
23    let completed = 0;
24
25    for (const task of this.tasks) {
26      await task();
27      completed += 1;
28      this.emit('progress', {
29        completed,
30        total,
31        percent: Math.round((completed / total) * 100),
32      });
33    }
34
35    this.emit('done', { total });
36  }
37}
38
39const queue = new SimpleQueue();
40queue.add(() => new Promise(r => setTimeout(r, 200)));
41queue.add(() => new Promise(r => setTimeout(r, 200)));
42queue.add(() => new Promise(r => setTimeout(r, 200)));
43
44queue.on('progress', info => console.log(info));
45queue.on('done', info => console.log('done', info));
46
47queue.run();

This pattern works whether the tasks represent file uploads, network calls, or data processing jobs.

Progress for Concurrent Queues

If the queue runs multiple tasks in parallel, progress still works the same way. The only difference is that completions may arrive in a different order.

The queue should increment its completed count whenever any task finishes successfully. If failed tasks also count as “finished,” decide that explicitly and document it.

That matters because a UI progress bar should not jump backward or hang at 80 percent because the definition of completion was unclear.

UI Integration

A browser UI usually wants a percentage and maybe a label.

javascript
queue.on('progress', ({ percent }) => {
  document.getElementById('status').textContent = `${percent}%`;
});

The queue logic should emit structured data. The UI layer should decide how to render it. That separation keeps the queue reusable outside the browser too.

Error Handling and Progress Semantics

Progress becomes ambiguous once failures enter the picture. You need to decide whether:

  • failed tasks count toward total completion
  • the queue stops on first error
  • the queue continues and reports failed count separately

A maintainable design often emits both progress and error events. That lets the caller choose between fail-fast behavior and “finish what you can” behavior.

Design for Observability, Not Just Completion

Queues are much easier to debug when events are explicit. Useful events often include:

  • task started
  • task completed
  • task failed
  • queue progress updated
  • queue finished

If you only emit a final completion event, the queue becomes a black box during long-running operations.

Common Pitfalls

A common mistake is calculating progress from tasks started rather than tasks finished. That makes the UI lie under concurrency.

Another mistake is forgetting to define how failures affect the progress percentage.

Developers also sometimes tightly couple queue logic to DOM updates or framework state, which makes the queue hard to test or reuse.

Finally, do not assume progress events are free. If you emit them too frequently for tiny tasks, the UI or logging system may become the bottleneck.

Summary

  • A queue progress event usually reports completed tasks versus total tasks.
  • Progress should be driven by actual task completion, not by task creation.
  • Emit structured progress data and let the UI decide how to display it.
  • Define clearly how failures affect progress and completion semantics.
  • A queue with progress events is much easier to monitor, debug, and integrate into user-facing workflows.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.