Search code examples
javascriptreactjsserverasync-awaithttpresponse

Why line of code isn't executed after awaiting server response


In a react component I havel the following code:  

const handleButton = async () => {
 
  const resp = await updateProject(projectInfo);
  setIsProjectModalVisible(false)

};

  updateProject() is a POST request to a server and setIsProjectModalVisible is a setState function from the parent component that was passed as a prop.

I was having a strange behavior: with the previous code, the Modal wouldn't be hidden (setIsProjetModalVisible(false) wouldn't run), but if I swapped the two lines:  

const handleButton = async () => {
 
  setIsProjectModalVisible(false)
  const resp = await updateProject(projectInfo);

};

it would work as expected and the Modal would become invisible.

After a bit of research, I identified the problem: the server wasn't responding to updateProject(). Fixing that, the second line of code would now result in the expected behavior.

Even though the problem is solved, I'd like to understand that behavior: since the server wasn't responding, I might expect an infinite wait in the await line, but while debugging, it would just skip that line and no error was shown. Why is that? Thanks!


Solution

  • When you call updateProject, it returns a Pending Promise. At first a pending promise wouldn't block the next following code setIsProjectModalVisible(false).

    But when you declare your function as async, and mark await to your promise you are stating that following code should only execute when your promise resolves. If the promise hangs on pending your code is blocked until the promise resolves.

    The promise could also rejects (you get a server timeout error or something else goes wrong), which would throw an error, but your code wouldn't be executed. Your app would crash, unless you had wrapped your promise in a try/catch block (which is recommended), where you would handle the error at the catch block properly.

    const handleButton = async () => {
      try {
        const resp = await updateProject(projectInfo);
        // if it rejects following code doesn't execute. jumps to catch block
        setIsProjectModalVisible(false)
      } catch (error) {
        // handle error here
        console.log(error)
      }
    };