From 1f2130ba0ec9210471d3e2195f58f7c9f7ef8a8a Mon Sep 17 00:00:00 2001 From: ilaiwi Date: Fri, 17 Apr 2020 13:17:09 +0300 Subject: [PATCH 1/5] add idle event --- readme.md | 24 ++++++++++++++++++++++++ source/index.ts | 3 ++- test/test.ts | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index eb11449..18e11ba 100644 --- a/readme.md +++ b/readme.md @@ -218,6 +218,30 @@ queue.add(() => Promise.resolve()); queue.add(() => Promise.resolve()); queue.add(() => delay(500)); ``` +#### idle + +Emitted when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`. + +```js +const delay = require('delay'); +const {default: PQueue} = require('p-queue'); + +const queue = new PQueue(); + +queue.on('idle', () => { + console.log(`Queue is idle. Size: ${queue.size} Pending: ${queue.pending}`); +}); + +const job1 = queue.add(() => delay(2000)); +const job2 = queue.add(() => delay(500)); + +await job1; +await job2; +// => 'Queue is idle. Size: 0 Pending: 0' + +await queue.add(() => delay(600)); +// => 'Queue is idle. Size: 0 Pending: 0' +``` ## Advanced example diff --git a/source/index.ts b/source/index.ts index d02e65c..cc039d7 100644 --- a/source/index.ts +++ b/source/index.ts @@ -18,7 +18,7 @@ const timeoutError = new TimeoutError(); /** Promise queue with concurrency control. */ -export default class PQueue = PriorityQueue, EnqueueOptionsType extends QueueAddOptions = DefaultAddOptions> extends EventEmitter<'active'> { +export default class PQueue = PriorityQueue, EnqueueOptionsType extends QueueAddOptions = DefaultAddOptions> extends EventEmitter<'active' | 'idle'> { private readonly _carryoverConcurrencyCount: boolean; private readonly _isIntervalIgnored: boolean; @@ -108,6 +108,7 @@ export default class PQueue { t.is(eventCount, items.length); }); +test('should emit idle event when idle', async t => { + const queue = new PQueue({concurrency: 1}); + + let timesCalled = 0; + queue.on('idle', () => { + timesCalled++; + }); + + const job1 = queue.add(async () => delay(100)); + const job2 = queue.add(async () => delay(100)); + + t.is(queue.pending, 1); + t.is(queue.size, 1); + t.is(timesCalled, 0); + + await job1; + + t.is(queue.pending, 1); + t.is(queue.size, 0); + t.is(timesCalled, 0); + + await job2; + + t.is(queue.pending, 0); + t.is(queue.size, 0); + t.is(timesCalled, 1); + + const job3 = queue.add(async () => delay(100)); + + t.is(queue.pending, 1); + t.is(queue.size, 0); + t.is(timesCalled, 1); + + await job3; + t.is(queue.pending, 0); + t.is(queue.size, 0); + t.is(timesCalled, 2); +}); + test('should verify timeout overrides passed to add', async t => { const queue = new PQueue({timeout: 200, throwOnTimeout: true}); From 3c0d75764790e20c2fe1be9930bef02f9862e931 Mon Sep 17 00:00:00 2001 From: ilaiwi Date: Fri, 17 Apr 2020 13:23:31 +0300 Subject: [PATCH 2/5] fix broken lint is tests --- test/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.ts b/test/test.ts index 5c7fecf..4242b5e 100644 --- a/test/test.ts +++ b/test/test.ts @@ -42,7 +42,7 @@ test('.add() - concurrency: 1', async t => { const end = timeSpan(); const queue = new PQueue({concurrency: 1}); - const mapper = async ([value, ms]: readonly number[]) => queue.add(async () => { + const mapper = async ([value, ms]: readonly number[]): Promise => queue.add(async () => { await delay(ms); return value; }); From 079fd407b28df6cef504f6e7b18f592bd65f0b70 Mon Sep 17 00:00:00 2001 From: Ahmad Ilaiwi Date: Thu, 30 Apr 2020 16:49:48 +0300 Subject: [PATCH 3/5] Update readme.md Co-authored-by: Sindre Sorhus --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 18e11ba..7a9e40f 100644 --- a/readme.md +++ b/readme.md @@ -220,7 +220,7 @@ queue.add(() => delay(500)); ``` #### idle -Emitted when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`. +Emitted every time the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`. ```js const delay = require('delay'); From 0e47a070ba3e145efb6715933adec4cfab32d134 Mon Sep 17 00:00:00 2001 From: ilaiwi Date: Thu, 30 Apr 2020 16:55:22 +0300 Subject: [PATCH 4/5] difference between idle and onIdle --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 7a9e40f..944c9ab 100644 --- a/readme.md +++ b/readme.md @@ -243,6 +243,8 @@ await queue.add(() => delay(600)); // => 'Queue is idle. Size: 0 Pending: 0' ``` +`idle` event gets called every time the queue reaches an idle state. On the other hand `onIdle()` callback is only called once when the queue becomes idle instead of every time the queue is idle. + ## Advanced example A more advanced example to help you understand the flow. From 51076e3472ccc5ce3437b3ca437220ec8360a892 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 3 May 2020 16:37:08 +0800 Subject: [PATCH 5/5] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 944c9ab..776b725 100644 --- a/readme.md +++ b/readme.md @@ -220,7 +220,7 @@ queue.add(() => delay(500)); ``` #### idle -Emitted every time the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`. +Emitted every time the queue becomes empty and all promises have completed; `queue.size === 0 && queue.pending === 0`. ```js const delay = require('delay'); @@ -243,7 +243,7 @@ await queue.add(() => delay(600)); // => 'Queue is idle. Size: 0 Pending: 0' ``` -`idle` event gets called every time the queue reaches an idle state. On the other hand `onIdle()` callback is only called once when the queue becomes idle instead of every time the queue is idle. +The `idle` event is emitted every time the queue reaches an idle state. On the other hand, the promise the `onIdle()` function returns resolves once the queue becomes idle instead of every time the queue is idle. ## Advanced example