From a9462e6b20cec2199fde2454ed8c2d00771fdc3b Mon Sep 17 00:00:00 2001 From: seognil LC Date: Sat, 22 Aug 2020 18:03:27 +0800 Subject: [PATCH] feat(js): add debounce-promise --- js/util/debounce-promise.ts | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 js/util/debounce-promise.ts diff --git a/js/util/debounce-promise.ts b/js/util/debounce-promise.ts new file mode 100644 index 0000000..a4a6e7d --- /dev/null +++ b/js/util/debounce-promise.ts @@ -0,0 +1,58 @@ +{ + // * ------------------------------------------------ debounceP + + const debounceP = (fn: (...args: T) => Promise, duration = 0) => { + let tick: NodeJS.Timeout; + + let singleP: Promise | null; + let singleRes: ((value: K) => void) | null; + let singleRej: ((reason?: any) => void) | null; + + return (...args: T) => { + if (singleP) { + clearTimeout(tick); + } else { + singleP = new Promise((res, rej) => { + singleRes = res; + singleRej = rej; + }); + } + + tick = setTimeout(() => { + clearTimeout(tick); + fn(...args!).then(singleRes, singleRej); + singleP = singleRes = singleRej = null; + }, duration); + + return singleP; + }; + }; + + // * ------------------------------------------------ test + + const delay = (n: number) => new Promise((res) => setTimeout(() => res(), n)); + + const fn = async (val: number) => { + console.log('run fn, args:', val); + await delay(100); + return val; + }; + + const dFn = debounceP(fn, 500); + + // * ---------------- + + (async () => { + dFn(1).then((e) => (console.log(e), console.assert(e === 3))); + dFn(2).then((e) => (console.log(e), console.assert(e === 3))); + dFn(3).then((e) => (console.log(e), console.assert(e === 3))); + + console.log('--------'); + await delay(1000); + console.log('--------'); + + dFn(6).then((e) => (console.log(e), console.assert(e === 8))); + dFn(7).then((e) => (console.log(e), console.assert(e === 8))); + dFn(8).then((e) => (console.log(e), console.assert(e === 8))); + })(); +}