skip to Main Content
import { useState } from 'react';

export default function Form() {
  const [text, setText] = useState('');

  function sleep(milliseconds) {
    const start = Date.now();
    while (Date.now() - start < milliseconds) {
    }
  }

  async function handleSubmit(e) {
    sleep(5000);
  }

  function handleTextareaChange(e) {
    setText(e.target.value);
  }

  return (
    <>
      <h2>Test</h2>
      <form onSubmit={handleSubmit}>
        <textarea
          value={text}
          onChange={handleTextareaChange}
        />
        <br />
        <button>
          Submit
        </button>
      </form>
    </>
  );
}

I edited this component from the react docs to make it to the point.

I was learning react and JavaScript and ran into async functions in the react docs.

Here when I submit the form I can not edit it until the sleep runs out, but my confusion is that the sleep(5000) was called inside an async function.

Calling functions inside async functions does not make them non-blocking?
Or, does the form also call await on the handleSubmit as well?

My knowledge on JavaScript and react is low, so I may not be using terms correctly.

2

Answers


  1. Just because a function is called inside an async function, it doesn’t automatically make that function non-blocking. The function itself needs to be asynchronous or involve an asynchronous operation (like await or Promise-based operations) to avoid blocking.

    function sleep(milliseconds) {
      return new Promise((resolve) => setTimeout(resolve, milliseconds));
    }
    
    async function handleSubmit() {
      await sleep(5000); // Non-blocking now because it's asynchronous
      // other logic
    }
    
    Login or Signup to reply.
  2. As you know, there are synchronous codes and asynchronous codes.

    For example, the below statement is synchronous. It will block execution of the main function until it finishes. Please see the output below.

    function sleep(milliseconds) {
      console.log('sleeping');
      const start = Date.now();
      while (Date.now() - start < milliseconds) {}
    }
    
    sleep();
    console.log('main function');
    

    Output

    sleeping
    main function
    

    However, the below statement is asynchronous, although it does not wait for even 1 millisecond. Please see the output, the main function logs before the sleep function.

    setTimeout(() => sleep(), 0);
    console.log('main function');
    

    Output

    main function
    sleeping
    

    What has been essentially happened in the above code is that we could write a synchronous statement executed in asynchronous manner.

    Now when we need to do the opposite, to write an asynchronous code in synchronous manner, how to do we it ? This is where the async keyword applies.

    In the code below, although the second asynchronous statement is timed out in 1 second, that statement still waits for the completion of the first asynchronous statement which finishes later in 2 seconds. It means that we could write two asynchronous statements to execute in synchronous manner. Please see below the output.

    async function asyncfunc() {
      await new Promise((resolve) =>
        setTimeout(() => {
          resolve(1);
          sleep();
          console.log('slept for 2000ms');
        }, 2000)
      );
      await new Promise((resolve) =>
        setTimeout(() => {
          resolve(1);
          sleep();
          console.log('slept for 1000ms');
        }, 1000)
      );
    }
    
    asyncfunc().then(() => {});
    console.log('main function');
    

    Output

    main function
    sleeping
    slept for 2000ms
    sleeping
    slept for 1000ms
    

    The summary is that the code needs to be asynchronous in nature to get it executed in async manner. In the above examples, setTimeout is the asynchronous function which makes the synchronous code asynchronous. A synchronous enclosed in a function with async keyword does not make the function executed asynchronously.

    However, the asynchronous statements enclosed in a function with async keyword makes the function to execute the asynchronous calls synchronously and execute the function as a whole still asynchronously. Please recall that in the above output, main function finishes earlier than the async function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search