Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS Event Handler: async function

I'm building an app with Cordova. On one page, there is an EventListener that calls an async function. window.addEventListener("load", loadEdit(), false);

The function looks like this async function loadEdit(){...}.

When testing in the browser I get the following error even though the function is fully executed:

TypeError: Property 'handleEvent' is not callable.

However, if I change the EventListener to another function which then calls the async function, there seems to be no problem. For example:

window.addEventListener("load", loadPre(), false);
...
function loadPre()
{
  loadEdit();
}
  1. What is the problem with an async function getting called by the EventListener?
  2. Why does it not detect that the second method also calls an async function?
like image 785
David E. Avatar asked May 31 '18 11:05

David E.


People also ask

Can event handlers be async JavaScript?

Event handlers are not Dispatched Asynchronously So even though you're making an await call, the source thread is the Main UI thread. So you actually may still be blocking even though your event handler is async .

Why is that using async function with event handler is problematic?

Using async functions with event handlers is problematic, because it can lead to an unhandled rejection in case of a thrown exception: const ee = new EventEmitter(); ee.

How can you access the event properties in an asynchronous way?

If you need to access an event in an asynchronous way, then you should call event. persist() at the beginning of the function.

What is an async function in JS?

An async function is a function declared with the async keyword, and the await keyword is permitted within it. The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains.


2 Answers

You can call an async function from your EventListener.

The first problem I see is that you are invoking the callback function right away in the second argument of window.addEventListener by including it as loadEdit() instead of loadEdit or () => loadEdit(). You have to give it a function as second argument, right now you are giving a Promise or the return value of loadPre().

Try this way:

window.addEventListener("load", () => loadEdit(), false);

async function loadEdit() {
    // do the await things here.
}

Async function return Promises. So, if you would like to do something after loadEdit, try:

window.addEventListener("load", () => {
    loadEdit().then(/* callback function here */);
}, false);

async function loadEdit() {
    // do the await things here.
}
like image 173
skovmand Avatar answered Sep 21 '22 01:09

skovmand


TL&DR: In order to use a call-back with an async function, you will need to decorate your async function within the Add Listener, and use await within the code block;

Explanation: As mentioned above in your example you are calling the function immediately; This means either two things will happen: Your function will return a value immediately OR you will get a promise; In either case its best to 'await' the call so the program runs more synchronously.

async function getStringSize(searchString) {
            return searchString.length;
        }

        txtInput.addEventListener("keyup", async e => {
            const searchString = e.target.value;
            total_length = await getStringSize(searchString);
            if (total_length > 3) {
    
                console.log(searchString);
            }
        }, false);
like image 26
FlyingV Avatar answered Sep 18 '22 01:09

FlyingV