user5228393
user5228393

Reputation:

When using await does it block the function it is used in?

I have this async function below:

async LoadEditForm() {
    const { default : EditHero } = await import('./EditHero');
    this.setState({ lazyEditHero: EditHero })
}

And it is called it here:

handleEnableAddMode = async () => {
    await this.LoadEditForm();
    this.setState({
        addingHero: true,
        selectedHero: { id: '', name: '', saying: '' }
    });
}  

I have a question regarding the code above:

  1. At this line: await this.LoadEditForm(); in the handleEnableAddMode function, does it block that function? In other words does the this.setState(...) function get called immediately or does it wait for the await call to finish.
    • Since I heard people saying the async/await concept is to allow you to write async code in a synchronous manner. That is kind of confusing me. Can someone clarify?

Upvotes: 0

Views: 106

Answers (3)

Jon Hanna
Jon Hanna

Reputation: 113242

At this line: await this.LoadEditForm(); in the handleEnableAddMode function, does it block that function? In other words does the this.setState(...) function get called immediately or does it wait for the await call to finish.

One of those is not the other one "in other words".

It doesn't block, it waits. The control will return to the caller of the async function. When the promise being waited on is resolved or rejected, then the waiting function will resume.

https://jsfiddle.net/7yxhqoo4/ has a simple example, thus:

function resolveAfterHalfSecond() { 
  return new Promise(resolve => {
    setTimeout(() => {
      resolve();
    }, 500);
  });
}

async function f1() {
  $("div").append("<p>before await</p>");
  await resolveAfterHalfSecond();
  $("div").append("<p>after await</p>");
}

function test()
{
  $("div").append("<p>before call async function</p>");
  f1();
  $("div").append("<p>after call async function</p>");
}

$(test);

The immediate output looks like:

before call async function

before await

after call async function

And after half a second, it looks like

before call async function

before await

after call async function

after await.

When the await was hit in f1() it didn't block, but immediately went back to test() and finished that function. When the promise was resolved, f1() resumed.

Upvotes: 1

Pedram marandi
Pedram marandi

Reputation: 1614

When you're calling an Asyc function, it will return a promise, whenever you return a value in your async function your promise will be resolved, and if you throw an exception, your promise is rejected. On the other side, the await expression pauses the execution of the async function and waits for the passed Promise's resolution, and then resumes the async function's execution and returns the resolved value.

Based on the provided samples in Mozile documentations:

function getProcessedData(url) {
  return downloadData(url) // returns a promise
    .catch(e => {
      return downloadFallbackData(url)  // returns a promise
    })
    .then(v => {
      return processDataInWorker(v); // returns a promise
    });
}


async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url); 
  } catch(e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}

In your case, your setState won't be executed until your await this.LoadEditForm(); be fulfilled. But the thing is you've not catch the probable rejection of your promise. So if the function b rejected, your setState will be executed anyway.

So you have to wrap the await function and the following lines in a try ... catch statement.

Upvotes: 1

tadman
tadman

Reputation: 211580

Typically await will hold until it receives either a successful result because the promise was "resolved", or it encounters an error because the promise was "rejected".

If neither of these two events occur, your promise is broken and the await may never complete.

Upvotes: 1

Related Questions