7

I'm having following code.

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
      function sleep( lf_ms ) {
        return new Promise( resolve => setTimeout( resolve, lf_ms ) );
      }

      async function check_form() {
        alert( 'Test 1' );
        await sleep( 1000 );
        alert( 'Test 2' );

        return false;
      }
    </script>
  </head>
  <body>
    <form name="myform" method="post" action="test.htm" onsubmit="return check_form();">
      <input type="text" name="city"><br>
      <br>
      <a href="javascript:check_form();">check the method call via link</a><br>
      <br>
      <button type="submit">check the method call via submit button</button><br>
      <br>
    </form>
  </body>
</html>

I want to sleep the function check_form() for 1 second.

If I click on the link, "Test 1" and "Test 2" will be displayed. If I click the submit button only "Test 1" is displayed. What am I doing wrong here?

My question is different from Submitting a form with submit() using Promise. Because the javascript event handler onsubmit is not used.

Rüdiger Schmidt
  • 73
  • 1
  • 1
  • 6
  • Possible duplicate of [Submitting a form with submit() using Promise](https://stackoverflow.com/questions/50360642/submitting-a-form-with-submit-using-promise) – Baboo Sep 04 '19 at 14:54
  • Why do you need to use `promise` here? – Daniyal Lukmanov Sep 04 '19 at 14:55
  • possible duplicate of https://stackoverflow.com/questions/33289726/combination-of-async-function-await-settimeout – Travis James Sep 04 '19 at 14:57
  • Hi Daniyal, I've been looking for a feature that will allow me to stop javascript and come across promise. – Rüdiger Schmidt Sep 04 '19 at 15:40
  • @RüdigerSchmidt Given your most recent edit, have you noticed my answer below? – Ivar Sep 04 '19 at 16:21
  • `await` does not "stop Javascript". It pauses the internal execution of the function, but as soon as you hit the first `await` in the function, the function returns a promise and other execution continues. So, you're just returning a promise from the submit handler and since the DOM code doesn't know what to do with the promise, it is ignored. There is no way to "stop" Javascript in the way you are thinking. – jfriend00 Sep 04 '19 at 16:29
  • @Ivar User input is checked in the function check_form. If the inputs are error-free, the function returns true. If there are errors, the function returns false. In the event of an error, the page that is stored in the attribute action of the tag form should not be called. – Rüdiger Schmidt Sep 05 '19 at 12:58
  • @RüdigerSchmidt See my updated answer. – Ivar Sep 05 '19 at 13:07

1 Answers1

13

The return check_form() does not return false as you might think. Async functions always return an implicit Promise and therefore, your form is still submitted. The first alert shows up because up to that moment it is still synchronous. Everything after the sleep will be scheduled for a later time and the form submission will not wait for that.

To resolve it you can call the function and then return false.

function sleep(lf_ms) {
  return new Promise(resolve => setTimeout(resolve, lf_ms));
}

async function check_form() {
  console.log('Test 1');
  await sleep(1000);
  console.log('Test 2');
}
<form name="myform" method="post" onsubmit="check_form(); return false;">
  <input type="text" name="city"><br>
  <br>
  <a href="javascript:check_form();">check the method call via link</a><br>
  <br>
  <button type="submit">check the method call via submit button</button><br>
  <br>
</form>

Edit to address your comment

User input is checked in the function check_form. If the inputs are error-free, the function returns true. If there are errors, the function returns false. In the event of an error, the page that is stored in the attribute action of the tag form should not be called.

You can't pause JavaScript like that, but you can use return false to stop the submission and then after your validation, submit the form via JavaScript.

function sleep(lf_ms) {
  return new Promise(resolve => setTimeout(resolve, lf_ms));
}

async function check_form(form) {
  console.log('Test 1');
  await sleep(1000);
  console.log('Test 2');

  let city = document.getElementById('city').value;
  // Validation
  if (form !== undefined && city.trim() !== "") {
    // Validation succeeded, submit the form
    form.submit();
  }
}
<form name="myform" method="post" onsubmit="check_form(this); return false;">
  <input type="text" id="city" name="city"><br>
  <br>
  <a href="javascript:check_form();">check the method call via link</a><br>
  <br>
  <button type="submit">check the method call via submit button</button><br>
  <br>
</form>
Ivar
  • 6,138
  • 12
  • 49
  • 61