I have an issue with preventing double (multiple) eventListener
handling in code:
var locked;
button.addEventListener("click", function() {
if (locked) return;
locked = true;
calculateSomethingHeavy();
locked = false;
}
Second immediate button click triggers another event, despite locked == true
. Things like button.disabled = true
or setTimeout(function() {locked = true;}, 0)
have no effect because (I guess) second call is stacked and will be invoked only after first is fully handled. I think I'm missing some whole technology of asynchronous event handling. How to do this in pure js?
An async function can handle a promise called within it using the await operator. await can be used within an async function and will wait until a promise settles before executing the designated code. The await operators here ensure that the data is not logged before the request has populated it with data.
Asynchronous programming is a technique that enables your program to start a potentially long-running task and still be able to be responsive to other events while that task runs, rather than having to wait until that task has finished.
Sync is single-thread, so only one operation or program will run at a time. Async is non-blocking, which means it will send multiple requests to a server. Sync is blocking — it will only send the server one request at a time and will wait for that request to be answered by the server.
Every line of code waits for its previous one to get executed first and then it gets executed. Asynchronous JavaScript: Asynchronous code allows the program to be executed immediately where the synchronous code will block further execution of the remaining code until it finishes the current one.
In synchronous operations tasks are performed one at a time and only when one is completed, the following is unblocked. In other words, you need to wait for a task to finish to move to the next one. In asynchronous operations, on the other hand, you can move to another task before the previous one finishes.
The correct answer here depends on the definition of calculateSomethingHeavy
. Presumably it's asynchronous based on the question title, but that could be implemented using callbacks, or events, or promises or async/await.
Regardless of which of those is at play here, what you need to do is ensure that locked
is not set to false
until after calculateSomethingHeavy
has finished.
That might look like the following in each case...
var locked;
button.addEventListener("click", function() {
if (locked) return;
locked = true;
calculateSomethingHeavy(() => {
locked = false;
});
});
var locked;
button.addEventListener("click", function() {
if (locked) return;
locked = true;
calculateSomethingHeavy().on('finish', () => {
locked = false;
});
});
var locked;
button.addEventListener("click", function() {
if (locked) return;
locked = true;
calculateSomethingHeavy()
.then(() => {
locked = false;
});
});
var locked;
button.addEventListener("click", async function() {
if (locked) return;
locked = true;
await calculateSomethingHeavy();
locked = false;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With