Skip to content

Commit

Permalink
Add onSizeLessThan helper method
Browse files Browse the repository at this point in the history
  • Loading branch information
dobesv committed Mar 26, 2021
1 parent 7036650 commit 8b2f388
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
10 changes: 10 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ Returns a promise that settles when the queue becomes empty, and all promises ha

The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet.

#### .onSizeLessThan(limit)

Returns a promise that settles when the queue size is less than the given limit; `queue.size < limit`.

If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before
adding a new item.

Note that this only limits the number of items waiting to start; there could still be up to `concurrency` jobs
already running that this call does not include in its calculation.

#### .clear()

Clear the queue.
Expand Down
22 changes: 22 additions & 0 deletions source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,28 @@ export default class PQueue<QueueType extends Queue<RunFunction, EnqueueOptionsT
});
}

/**
Wait for the queue size (the number of items not yet started) to fall below a certain threshold
@returns A promise that settles when the queue size is below the given limit
*/
async onSizeLessThan(limit: number): Promise<void> {
// Instantly resolve if the queue is empty
if (this._queue.size < limit) {
return;
}

return new Promise<void>(resolve => {
const listener = () => {
if(this._queue.size < limit) {
this.removeListener('next', listener);
resolve();
}
}
this.on('next', listener);
});
}

/**
The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet.
Expand Down
25 changes: 25 additions & 0 deletions test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,31 @@ test('.onIdle()', async t => {
t.is(queue.pending, 0);
});

test('onSizeLessThan()', async t => {
const queue = new PQueue({concurrency: 1});

queue.add(async () => delay(100));
queue.add(async () => delay(100));
queue.add(async () => delay(100));
queue.add(async () => delay(100));
queue.add(async () => delay(100));

await queue.onSizeLessThan(4);
t.is(queue.size, 3);
t.is(queue.pending, 1);

await queue.onSizeLessThan(2);
t.is(queue.size, 1);
t.is(queue.pending, 1);

await queue.onSizeLessThan(10);
t.is(queue.size, 1);
t.is(queue.pending, 1);

await queue.onSizeLessThan(1);
t.is(queue.size, 0);
t.is(queue.pending, 1);
})
test('.onIdle() - no pending', async t => {
const queue = new PQueue();
t.is(queue.size, 0);
Expand Down

0 comments on commit 8b2f388

Please sign in to comment.