TransWikia.com

How can I await an event listener inside a function?

Stack Overflow Asked on December 4, 2021

I’m trying to wait for a button to be clicked before proceeding inside another function.

async function foo() {
    // code before
    await ??? // wait for start button to be clicked before proceeding
    // code after
}

startButton.addEventListener("click", function() {
    return new Promise(); // ???
}, false);

How can I use an event listener inside another function?

4 Answers

you can use an anonymous function and call it itself.

await (async () => {
    return new Promise((res) => {
        btn.onclick= () => res(true);
    });
})();

use like this

async function foo() {

    await (async () => {
        return new Promise((res) => {
            btn.onclick= () => res(true);
        });
    })();
    
    //do whatever
}

Answered by himansa eshan on December 4, 2021

You may be able to get this to work, but probably shouldn't.

Having one large function that does stuff, waits for input, and then does more stuff is cumbersome and hard to reason about.

Event listeners are there to help you with the "waiting for user input" problem without having to wrangle your code around it. By having a function start and then wait for an event listener to fire, you are kind of undoing that pattern.

In fact, many programmers consider having to create the first Promise in a chain to be an "anti-pattern", which means it goes against the grain of good practices. But the bigger problem here is how the bulk of this one big function will weigh you down in the future.

Instead, try splitting up your function. For instance:

function preInput(){
    //some setup tasks here
}

function postInput(){
    //some post-input tasks here
}

preInput(); // or elsewhere, depending on needs
startButton.addEventListener("click", postInput);

That's a lot easier to follow, and add to, in the future.

Answered by tmdesigned on December 4, 2021

You're on the right track with returning a new Promise(). You can do something along these lines:

async btnClick(btn) {
    return new Promise(resolve =>  btn.onclick = () => resolve());
}

then in your calling code:

await btnClick(startButton);

Answered by JohanP on December 4, 2021

You can proceed like this:

// click the first button to begin the process
document.getElementById('beginbtn').addEventListener('click', function () {
  foo();
});


// foo
async function foo() {
  // hide the begin button
  document.getElementById('beginbtn').style.display = 'none';
  
  // show the pass button
  document.getElementById('passbtn').style.display = 'block';
  
  /******* FOCUS HERE ******/
  console.log('-- begin ... click "PASS" to continue -- ');
  await bar();
  console.log('-- end -- ');
  /******* FOCUS HERE ******/
  
  // show the begin button
  document.getElementById('beginbtn').style.display = 'block';
  
  // hide the pass button
  document.getElementById('passbtn').style.display = 'none';
}


// bar
function bar() {
  return new Promise(function (resolve, reject) {
    document.getElementById('passbtn').addEventListener('click', function () {
      console.log('clicked !!!');
      resolve();
    });
  });
}
<button id="beginbtn">CLICK TO BEGIN</button>
<button id="passbtn" style="display:none;">PASS</button>

Two buttons: begin and pass. First the begin button is shown and pass button hidden. Once clicked, the begin button starts the foo(). The process then starts and wait for bar to be resolved by clicking on pass button(which is now shown while begin button is hidden) to continue until end.

Hope it will help !

Answered by Missa Constant Pierre hardwork on December 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP