The following code works as expected; it processes a click
event and only allows a subsequent click
event to occur once the current one is finished processing.
However, since the IIEF closure is async
, the return value is Promise<void>
, which means that it breaks the no-misused-promises
rule with an error of Promise returned in function argument where a void return was expected
. Taking away the async
is not an option because it would result in having to remove the await
on handleClick()
, which has resulted in improper throttling of the click events when tested.
let processingClick = false;
document.getElementById(wikiPageElementId)?.addEventListener('click', async (event) => {
event.preventDefault();
if (!processingClick) {
processingClick = true;
// `await` needed here so that each event is processed synchronously.
// Without `await`, any subsequent click could be processed asynchronously
// while `handleClick()` is running.
await handleClick(event.target);
processingClick = false;
}
});
CodePudding user response:
There's no need for an IIFE (or an async IIFE) here - using .then
or .finally
will work just as well. (Consider .finally
, because it'll handle both successes and failures)
let processingClick = false;
document.getElementById(wikiPageElementId)?.addEventListener('click', (event) => {
event.preventDefault();
if (processingClick) {
return;
}
processingClick = true;
handleClick(event.target)
.finally(() => {
processingClick = false;
});
});
If you had to use an IIFE, you could declare it inside the click listener.
let processingClick = false;
document.getElementById(wikiPageElementId)?.addEventListener('click', (event) => {
event.preventDefault();
void (async () => {
if (!processingClick) {
processingClick = true;
await handleClick(event.target);
processingClick = false;
}
})();
});
(though that may run afoul of other linting rules you may have - the void
is needed for no-floating-promises
, but you also might have no-void
- which is why a better approach would be to avoid async IIFEs entirely)