Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .onSizeLessThan() helper method #131

Merged
merged 8 commits into from
Mar 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ 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
25 changes: 25 additions & 0 deletions source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,31 @@ export default class PQueue<QueueType extends Queue<RunFunction, EnqueueOptionsT
});
}

/**
@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.
*/
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);
dobesv marked this conversation as resolved.
Show resolved Hide resolved
});
}

/**
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
26 changes: 26 additions & 0 deletions test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,32 @@ 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