Xu Young
Xu Young

Reputation: 33

Why my async/await function is abnormal?(Javascript)

This is my Javascript coding. I think the results are 1 2 3 4 5.

async function fn1 () {
    console.log(1);
    await fn2();
    console.log(3);
};

async function fn2 () {
    console.log(2);
};

fn1();
new Promise((resolve, reject) => {
    console.log(4)
    resolve()
}).then(() => {
    console.log(5)
})

But. The results are: 1 2 4 5 3.

Upvotes: 3

Views: 221

Answers (4)

viz
viz

Reputation: 1277

// functions declaration

async function fn1 () {
    console.log(1);
    await fn2(); // wait for async function fn2(which gets dispatched on thread 3) => so console.log(2) should be here chronologically
    console.log(3);
};

async function fn2 () {
    console.log(2);
};


// thread 1 starts (the actual execution code)

fn1(); // since fn1 is async it gets dispatched on thread 2

new Promise((resolve, reject) => {
    console.log(4)
    resolve() // trigger () => {console.log(5)}
}) // promise declaration
.then(() => {
    console.log(5)
}) // execute the promise right away

Put it simple, console.log(1), console.log(2), console.log(3) happens on one thread chronologically, console.log(4), console.log(5) happens on the other thread chronologically. And they are intersecting each other.

Side Note: JavaScript itself is single-threaded and does not support multi-threading!(aside from web worker etc., in our context of "async") I simplified a lot and used the term thread here just to make it easy to be understood. In order not to mislead you on the concept of asynchronous operations, I recommend you to have a read on this QnA if you are not really sure on how async works in JavaScript.

Upvotes: 5

HMR
HMR

Reputation: 39250

You have to understand stack and queue:

More information: stack and queue video or ducumentation

When you do a new Promise(fnResolvingOrRejecting) the function fnResolvingOrRejecting is immediately called so it's on the same stack. Nothing is queued yet.

If you understand what stack and queue is you could explain your code better omitting the confusing async and await syntax.

The syntax would really improve code once you understand what it actually does but in this case I'll leave it out so you can see what code is executed as a callback/result handler and what code is on stack.

function fn1 () {
  console.log(1);//on the same stack as calling fn1
  fn2()//executing fn2
  .then(//first queued
    () => console.log(3)
  );
};

function fn2 () {
  return new Promise(
    (resolve)=>{
      console.log(2);//on the same stack as calling fn1
      resolve();
    }
  );
};

fn1();//calling fn1 immediatly logs 1 and 2 because they are on the same stack
new Promise((resolve, reject) => {
  //after calling fn1 and queing console.log(3) this is executed because it's on
  //  the same stack
  console.log(4)
  resolve()
}).then(() => {//second queued
  console.log(5)
})

Upvotes: 0

Nic Olas
Nic Olas

Reputation: 471

The executions of fn1() and new Promise() above are executed asynchronously, that's why the order of instructions are independent. If you want to have your desired result you can try below code:

async function fn1 () {
    console.log(1);
    await fn2();
    console.log(3);
};

async function fn2 () {
    console.log(2);
};

async function makeExectionOrder(){ // move the blocks into asynch function
    await fn1(); // make synchrounous call
    new Promise((resolve, reject) => {
        console.log(4)
        resolve()
    }).then(() => {
        console.log(5)
    })

}

makeExectionOrder()

Upvotes: 0

Fabiano
Fabiano

Reputation: 1413

The thing is that JS code are essentially async. So, before it executes the '3' printing, it already has fired the other instructions and theses ends before that ending.

Upvotes: 0

Related Questions