I have a base async function that returns a Promise
function asyncFoo(): Promise<void> {
return new Promise<void>((resolve, reject) => {
// I'm using here a setTimeout to fake async flow, in reality I'm making a server call
setTimeout(() => {
resolve();
}, 5000);
});
}
I can use my method
const promise = asyncFoo();
promise.then(() => {
console.log('Hello');
});
However if I debounce my function, the result function doesn't return anything, and I can't wait for it to resolve
const debounceFoo = _.debounce(asyncFoo, 100);
debounceFoo(); // undefined
// I would like to do something like
// debounceFoo().then(...) this will not work
How can I debounce the events (aggregate them) that happen during the debounce-time, then execute my asyncFoo(). And finally, act on its resolve callback?
You can use promise to do this:
const debounceAsync = (func, wait) => {
let timerID = -1;
return (...args) => {
clearTimeout(timerID);
const promiseForFunc = new Promise((resolve) => {
timerID = setTimeout(resolve, wait);
});
return promiseForFunc.then(() => func(...args));
};
};
const debounceFoo = debounceAsync(asyncFoo, 100);
debounceFoo().then(() => {
console.log('Hello');
});
The debounced function which return by lodash debounce usually return undefined before first time your func was invoked.
https://github.com/lodash/lodash/blob/2f79053d7bc7c9c9561a30dda202b3dcd2b72b90/debounce.js#L184-L206
Not sure about lodash's implementation but you can write your own debounce as this.
function debounce(func, timeout) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, timeout);
};
}
function asyncBar() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Hi");
resolve();
}, 4000);
});
}
const foo = debounce(async () => asyncBar(), 5000);
foo();