Skip to content

Counter

Eugene Lazutkin edited this page Mar 10, 2026 · 7 revisions

Description

Since version 1.2.0.

Counter is a utility class for tracking a numeric value, typically used to monitor the number of pending tasks or outstanding operations. It provides mechanisms to increment, decrement, or set the counter directly, and enables asynchronous waiting until the counter reaches zero or any custom condition. This makes it suitable for coordination in concurrent or asynchronous workflows.

Key features

  • Simple interface for incrementing, decrementing, and setting a counter value
  • Asynchronous waiting for the counter to reach zero or a custom condition
  • Immediate resolution of waiters if the condition is already met
  • Ability to clear all pending waiters

Technical specifications

Counter is available as a named and default export.

import Counter from 'time-queues/Counter.js';

const counter = new Counter(2); // Start with count 2

Constructor parameters

  • initial (number, optional): The initial count. Defaults to 0.

Instance properties

  • count (number): The current value of the counter.
  • value (number): Getter/setter for the counter value.

Instance methods

  • increment(): Increments the counter by 1.
  • decrement(): Decrements the counter by 1.
  • advance(amount = 1): Advances the counter by the specified amount (default: 1).
  • waitForZero(): Returns a Promise that resolves when the counter reaches zero. Resolves immediately if already zero.
  • waitFor(fn): Returns a Promise that resolves when the provided function fn(count) returns true. Resolves immediately if already true.
  • clearWaiters(): Clears all pending waiters, resolving them with NaN.

Internal methods

  • notify(): Notifies all waiters if their condition is met. (Called internally.)

Usage instructions

To use the Counter class, import it and create an instance. You can increment or decrement the counter, and wait for it to reach zero:

import Counter from 'time-queues/Counter.js';

const counter = new Counter();

// Increment when starting an async task
counter.increment();

// Decrement when the task finishes
counter.decrement();

// Wait for all tasks to complete
await counter.waitForZero();

You can also wait for custom conditions:

await counter.waitFor(count => count <= 5); // Wait until count is 5 or less

Troubleshooting

  • Promise never resolves: Ensure that you are correctly decrementing or advancing the counter so that the awaited condition can be met.
  • Waiters resolve with NaN: This happens if clearWaiters() is called before the condition is met.
  • Counter not updating as expected: Double-check that you are using increment(), decrement(), and advance() appropriately, and that you are not overwriting the counter value unexpectedly without using the setter.

If you encounter other issues, verify that you are not manipulating the counter from multiple places in a way that could lead to race conditions.

See Also

Clone this wiki locally