Pause function execution until another function returns

11,350

Solution 1

It is not possible. You cannot write a JavaScript function that blocks execution, gathers user input and returns a value based on user input. The only way to block execution and wait for user input is to use confirm.

You have to refactor your code to use callbacks if you want to use custom dialogs.

See Emulate Javascript 'alert' blocking nature

Solution 2

You can do something similar to this using async/await which is part of ES7.

async function stepTwo()
{
  return new Promise((resolve) =>
  {
    let stop = false;
    $('input[type=checkbox]').one('change', (event) =>
    {
      // Will only stop the loop when the checkbox is checked
      if (event.target.checked === true)
      {
        stop = true;
      }
    });
    loop();

    // Continues looping until stop is set to true (i.e. input has been done)
    function loop()
    {
      if (stop === true)
      {
        resolve();
        return;
      }

      // Keeps checking if stop is true
      setTimeout(loop, 100);
    }
  });
}

async function stepOne()
{
  $('div').text('Waiting for input..');
  // Waits for promise returned from stepTwo() to resolve
  await stepTwo();
  $('div').text('Input checked!');
}

// Starts the async function (any lines below this continue execution)
stepOne();

Fiddle: https://jsfiddle.net/1rvn5bfp/7/

Share:
11,350
Kerry Ritter
Author by

Kerry Ritter

Updated on August 29, 2022

Comments

  • Kerry Ritter
    Kerry Ritter over 1 year

    I am wanting to replace Magento's implementation of the alert() and confirm() dialog boxes. While the alert() replacement was trivial, I am unsure of how to handle the confirm() dialog. Is there a way to prevent JavaScript from continuing until a function is returned? Will this require looping that could crash a browser?

    So for example, I need to replace code like this:

    <form action="" method="POST">
       <input type="submit" onclick="return confirm('Are you sure?');" value="Delete">
    </form>
    

    with...

    <form action="" method="POST">
       <input type="submit" onclick="return myCustomConfirm('Are you sure?');" value="Delete">
    </form>
    

    Or other scenarios such as:

    <script>
       var delete = confirm('Are you sure?');
       if (delete) {
           doSomething();
       }
    </script>
    

    with...

    <script>
       var delete = myCustomConfirm('Are you sure?');
       if (delete) {
           doSomething();
       }
    </script>
    

    In both scenarios, myCustomConfirm() will open a Bootstrap modal where the user must click "Okay", "Cancel", or close the modal. The value returns true if "Okay" and false if otherwise.

    I don't want to do callbacks as that will cause more refactoring than desirable. Is this possible to do in another way?

    Thanks!

  • Ruan Mendes
    Ruan Mendes almost 10 years
    The OP said they didn't want to use callbacks?
  • cregox
    cregox about 7 years
    for the sake of completeness, alert and prompt also "blocks execution", although they are indeed simply variations of confirm