Skip to content

Commit 8d0a356

Browse files
dobesvsindresorhus
andauthored
Add .onSizeLessThan() helper method (#131)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 1ed5b4c commit 8d0a356

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

readme.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ Returns a promise that settles when the queue becomes empty, and all promises ha
155155

156156
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.
157157

158+
#### .onSizeLessThan(limit)
159+
160+
Returns a promise that settles when the queue size is less than the given limit: `queue.size < limit`.
161+
162+
If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before adding a new item.
163+
164+
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.
165+
158166
#### .clear()
159167

160168
Clear the queue.

source/index.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,31 @@ export default class PQueue<QueueType extends Queue<RunFunction, EnqueueOptionsT
328328
});
329329
}
330330

331+
/**
332+
@returns A promise that settles when the queue size is less than the given limit: `queue.size < limit`.
333+
334+
If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before adding a new item.
335+
336+
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.
337+
*/
338+
async onSizeLessThan(limit: number): Promise<void> {
339+
// Instantly resolve if the queue is empty.
340+
if (this._queue.size < limit) {
341+
return;
342+
}
343+
344+
return new Promise<void>(resolve => {
345+
const listener = () => {
346+
if (this._queue.size < limit) {
347+
this.removeListener('next', listener);
348+
resolve();
349+
}
350+
};
351+
352+
this.on('next', listener);
353+
});
354+
}
355+
331356
/**
332357
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.
333358

test/test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,32 @@ test('.onIdle()', async t => {
225225
t.is(queue.pending, 0);
226226
});
227227

228+
test('.onSizeLessThan()', async t => {
229+
const queue = new PQueue({concurrency: 1});
230+
231+
queue.add(async () => delay(100));
232+
queue.add(async () => delay(100));
233+
queue.add(async () => delay(100));
234+
queue.add(async () => delay(100));
235+
queue.add(async () => delay(100));
236+
237+
await queue.onSizeLessThan(4);
238+
t.is(queue.size, 3);
239+
t.is(queue.pending, 1);
240+
241+
await queue.onSizeLessThan(2);
242+
t.is(queue.size, 1);
243+
t.is(queue.pending, 1);
244+
245+
await queue.onSizeLessThan(10);
246+
t.is(queue.size, 1);
247+
t.is(queue.pending, 1);
248+
249+
await queue.onSizeLessThan(1);
250+
t.is(queue.size, 0);
251+
t.is(queue.pending, 1);
252+
});
253+
228254
test('.onIdle() - no pending', async t => {
229255
const queue = new PQueue();
230256
t.is(queue.size, 0);

0 commit comments

Comments
 (0)