Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous event handling in JavaScript

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?

like image 607
Roman Sergeev Avatar asked Jul 08 '18 20:07

Roman Sergeev


People also ask

How asynchronous events are handled in JavaScript?

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.

What is asynchronous process in JavaScript?

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.

What is difference between synchronous and asynchronous JavaScript?

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.

What is asynchronous request in JavaScript?

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.

What is synchronous and asynchronous in JavaScript with example?

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.


1 Answers

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...

Callbacks

var locked;

button.addEventListener("click", function() {
    if (locked) return;
    locked = true;
    calculateSomethingHeavy(() => {
        locked = false;
    });
});

Events

var locked;

button.addEventListener("click", function() {
    if (locked) return;
    locked = true;
    calculateSomethingHeavy().on('finish', () => {
        locked = false;
    });
});

Promises

var locked;

button.addEventListener("click", function() {
    if (locked) return;
    locked = true;
    calculateSomethingHeavy()
        .then(() => {
            locked = false;
        });
});

async/await

var locked;

button.addEventListener("click", async function() {
    if (locked) return;
    locked = true;
    await calculateSomethingHeavy();
    locked = false;
});
like image 79
Phil Booth Avatar answered Sep 21 '22 19:09

Phil Booth