From f913c26d81a6afde6a79eb18473bad21166f3b0c Mon Sep 17 00:00:00 2001 From: bdistin Date: Sat, 17 Aug 2019 10:57:45 -0500 Subject: [PATCH] feat(Collector): allow collectors to be consumed by for-await-of loops (#3269) --- src/structures/interfaces/Collector.js | 31 ++++++++++++++++++++++++++ typings/index.d.ts | 1 + 2 files changed, 32 insertions(+) diff --git a/src/structures/interfaces/Collector.js b/src/structures/interfaces/Collector.js index cadb44c65a58..3cd5d387e7c1 100644 --- a/src/structures/interfaces/Collector.js +++ b/src/structures/interfaces/Collector.js @@ -196,6 +196,37 @@ class Collector extends EventEmitter { if (reason) this.stop(reason); } + /** + * Allows collectors to be consumed with for-await-of loops + * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of} + */ + async *[Symbol.asyncIterator]() { + const queue = []; + const onCollect = item => queue.push(item); + this.on('collect', onCollect); + + try { + while (queue.length || !this.ended) { + if (queue.length) { + yield queue.shift(); + } else { + // eslint-disable-next-line no-await-in-loop + await new Promise(resolve => { + const tick = () => { + this.off('collect', tick); + this.off('end', tick); + return resolve(); + }; + this.on('collect', tick); + this.on('end', tick); + }); + } + } + } finally { + this.off('collect', onCollect); + } + } + toJSON() { return Util.flatten(this); } diff --git a/typings/index.d.ts b/typings/index.d.ts index 51b0d993c551..0d2422b63974 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -363,6 +363,7 @@ declare module 'discord.js' { public handleCollect(...args: any[]): void; public handleDispose(...args: any[]): void; public stop(reason?: string): void; + public [Symbol.asyncIterator](): AsyncIterableIterator; public toJSON(): object; protected listener: Function;