There is a search input with handler using ordinary debounce function (Vue component):
created() {
this.handleChange = debounce(async (ev) => {
this.loading = true;
const { target: { value: search } } = ev;
if (search) {
const response = await searchRepos({ search });
const repos = await response.json(response);
console.log(search);
console.log(repos?.items);
this.repos = repos?.items;
} else {
this.repos = [];
}
this.loading = false;
}, 500);
}
debounce
const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(null, args);
}, wait);
};
}
Works fine, but here is a moment. Callbacks are not waiting each other and it might create a situation, when previous callback return value after the next callback.
For example, sending a request when user erase penult symbol, during this user erase last and its callback ending faster, because of no request. Then previous callback return value, and non valid info shows up. Even tough we send request, there is no guarantee we receive response after previous.
My solution is in improving debounce like this:
export const debounce = (callback, waitTime) => {
let timeoutId = null;
let isPreviousPerforming = false;
let callbacksOrder = [];
const performRest = async () => {
for (const order of callbacksOrder) {
await callback.apply(null, [order.ev]);
}
callbacksOrder = []
};
return (ev) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(async () => {
if (isPreviousPerforming) {
callbacksOrder.push({ ev });
return;
}
isPreviousPerforming = true;
await callback.apply(null, [ev]);
await performRest();
isPreviousPerforming = false;
}, waitTime);
};
}
But here is a moment again: small probability that between for
and callbacksOrder = []
we could receive an event that will be pushed to callbacksOrder and we will delete it. Or do I misunderstand something?
QUESTION: What are possible solution or best practice to handle search input this way?
P.S. v-debounce works similar ordinary debounce.
Callbacks should be solved successively.