From 88056bed05ad1e601c59328bcb03ea30f5bcb4fe Mon Sep 17 00:00:00 2001 From: Rychu Date: Thu, 28 Jul 2022 12:09:04 +0200 Subject: [PATCH] Add `.off()` method for events (#2092) --- documentation/1-promise.md | 25 +++++++++++++++++++++++ source/as-promise/index.ts | 5 +++++ source/core/index.ts | 1 + test/progress.ts | 41 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/documentation/1-promise.md b/documentation/1-promise.md index 952b6cd41..3f5c5361f 100644 --- a/documentation/1-promise.md +++ b/documentation/1-promise.md @@ -89,3 +89,28 @@ Whether the promise is canceled. ### `promise.on(event, handler)` The events are the same as in [Stream API](3-streams.md#events). + +### `promise.off(event, handler)` + +Removes listener registered with [`promise.on`](1-promise.md#promiseonevent-handler) + +```js +import {createReadStream} from 'node:fs'; +import got from 'got'; + +const ongoingRequestPromise = got.post(uploadUrl, { + body: createReadStream('sample.txt') +}); + +const eventListener = (progress: Progress) => { + console.log(progress); +}; + +ongoingRequestPromise.on('uploadProgress', eventListener); + +setTimeout(() => { + ongoingRequestPromise.off('uploadProgress', eventListener); +}, 500); + +await ongoingRequestPromise; +``` diff --git a/source/as-promise/index.ts b/source/as-promise/index.ts index 95ce06dd2..5e7bd2bb4 100644 --- a/source/as-promise/index.ts +++ b/source/as-promise/index.ts @@ -170,6 +170,11 @@ export default function asPromise(firstRequest?: Request): CancelableRequest< return promise; }; + promise.off = (event: string, fn: (...args: any[]) => void) => { + emitter.off(event, fn); + return promise; + }; + const shortcut = (responseType: Options['responseType']): CancelableRequest => { const newPromise = (async () => { // Wait until downloading has ended diff --git a/source/core/index.ts b/source/core/index.ts index 01a12128e..079d349ac 100644 --- a/source/core/index.ts +++ b/source/core/index.ts @@ -117,6 +117,7 @@ export type GotEventFunction = export interface RequestEvents { on: GotEventFunction; once: GotEventFunction; + off: GotEventFunction; } export type CacheableRequestFunction = ( diff --git a/test/progress.ts b/test/progress.ts index ffd5ad147..26924f15b 100644 --- a/test/progress.ts +++ b/test/progress.ts @@ -221,3 +221,44 @@ test('upload progress - no body', withServer, async (t, server, got) => { }, ]); }); + +test('upload progress - no events when immediatly removed listener', withServer, async (t, server, got) => { + server.post('/', uploadEndpoint); + + const events: Progress[] = []; + + const listener = (event: Progress) => events.push(event); + + const promise = got.post('') + .on('uploadProgress', listener) + .off('uploadProgress', listener); + + await promise; + + t.is(events.length, 0); +}); + +test('upload progress - one event when removed listener', withServer, async (t, server, got) => { + server.post('/', uploadEndpoint); + + const events: Progress[] = []; + + const promise = got.post(''); + + const listener = (event: Progress) => { + events.push(event); + void promise.off('uploadProgress', listener); + }; + + void promise.on('uploadProgress', listener); + + await promise; + + t.deepEqual(events, [ + { + percent: 0, + transferred: 0, + total: undefined, + }, + ]); +});