AL-zami
AL-zami

Reputation: 9066

code inside async function executes before the code that follows it

I'm currently exploring the concept of async/await in javascript.I know that async function returns a promise which supposed to resolve in a future time and it doesn't block the natural execution of code.Here I have a code which i wrote to test the async execution of javascript.

console.log("1")
async function asyncFunc(){
  for(i=0;i<10000000;i++){
  }
  console.log("3")
}
asyncFunc().then(()=>{console.log('4')});
console.log("2");

I except the code will be executed in the following fashion:

first console.log() prints 1

secondly async function is called. As async code is non blocking,last console.log() will execute and thus prints 2 in the console.

After that console.log() inside async function will be executed and will print 3 in console.

lastly the promise will be resolved and console.log() inside then will be executed and prints 4.

so expected output : 1,2,3,4

but in reality I get output as 1,3,2,4.

why it behaves like this and not the way I expected

Upvotes: 3

Views: 1228

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074335

Late answer here, and Quentin is exactly right, but it's helpful sometimes to diagram these things. Let's look at really simple async function:

async function foo() {
    console.log("a");
    await something();
    console.log("b");
    return 42;
}

That function has two parts:

  • A synchronous part: Everything up to (but not including) the first await or return (or if it just ends). So in the above, that's the console.log("a"); and the call to something (but not the bit waiting for its result).
  • An asynchronous part: Anything following that first await.

If we were to rewrite that function with explicit promises, it would look something like this (hand-waving away details):

function foo() {
    console.log("a");
    return something().then(() => {
        console.log("b");
        return 42;
    });
}

So looking at your function:

async function asyncFunc(){
  for(i=0;i<10000000;i++){
  }
  console.log("3")
}

...we can see that all of the code in the function is in its initial synchronous part, and the promise it returns will be resolved with undefined.

So why do async functions have a synchronous part? For the same reason the executor function you pass into new Promise runs synchronously: So it can start its work right away.

Suppose we wanted to do an async wrapper around fetch where we expect a JSON response:

async function fetchJSON(...args) {
    const response = fetch(...args);
    return response.json();
};

If that didn't have a synchronous part (the call to fetch(...args)), it would never do anything and its promise would never be settled.

Upvotes: 2

Quentin
Quentin

Reputation: 943564

The function doesn't return a promise until it has finished running (unless you await another promise inside it).

The loop runs (blocking everything), then console.log("3") is evaluated, then it returns a promise.

The calling function continues to run (logging 2).

Finally, the event loop is freed up and the function passed to then is called.

Marking a function as async doesn't turn synchronous code inside it into asynchronous code.

Upvotes: 6

Related Questions