From 3f258c0d7d8fda210df63df9b3bf44361b4d6437 Mon Sep 17 00:00:00 2001 From: Wroud Date: Wed, 30 Jun 2021 14:56:11 +0300 Subject: [PATCH] feat(core-utils): CB-1068 throttleAsync --- webapp/packages/core-utils/src/throttle.ts | 51 ++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/webapp/packages/core-utils/src/throttle.ts b/webapp/packages/core-utils/src/throttle.ts index 76d21da155..69e969bdd4 100644 --- a/webapp/packages/core-utils/src/throttle.ts +++ b/webapp/packages/core-utils/src/throttle.ts @@ -6,6 +6,8 @@ * you may not use this file except in compliance with the License. */ +type ThrottleAsync = (...args: TArguments) => Promise; + export function throttle void | Promise>(f: T, delay: number): T { let throttle = false; let pending = false; @@ -38,3 +40,52 @@ export function throttle void | Promise>(f: } } as T; } + +export function throttleAsync< + TResult, + TArguments extends any[], + T extends (...args: TArguments) => Promise +>(f: T, delay: number): ThrottleAsync { + let throttle = false; + let _resolve: ((result: TResult) => void) | null = null; + let _reject: ((reason?: any) => void) | null = null; + let functionArgs: TArguments | null = null; + let thisObject: any; + + return async function exec(this: any, ...args: TArguments): Promise { + if (throttle) { + functionArgs = args; + thisObject = this; + + if (_reject) { + _reject(); + } + + return new Promise((resolve, reject) => { + _resolve = resolve; + _reject = reject; + }); + } + + throttle = true; + + try { + return f.apply(this, args); + } finally { + setTimeout(() => { + throttle = false; + + if (functionArgs) { + f.apply(thisObject, functionArgs) + .then(_resolve) + .catch(_reject); + + _resolve = null; + _reject = null; + thisObject = null; + functionArgs = null; + } + }, delay); + } + }; +}