3

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.

Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
Xu Young
  • 33
  • 4

4 Answers4

5

// 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.

viz
  • 1,247
  • 16
  • 27
  • async function init () { // codes same as above // but await fn1() } init() if I use a function to call theses, My results are 1 2 3 4 5. why is that? – Xu Young Dec 15 '17 at 06:11
  • @XuYoung That's simply because you are waiting for `fn1()` to be executed before you do anything with `Promise`. – viz Dec 15 '17 at 06:25
  • @XuYoung I edited my comment. My bad for the confusion if you had seen the previous one before the edit. `await` is only valid in `async` function. – viz Dec 15 '17 at 06:30
  • So anyway, if you do `async function init () { // codes same as above // but await fn1() } init()`, thread 1 will then wait for `fn1()`(which has been dispatched to thread 2) to be completed, which makes `console.log(1) // in thread 2` `console.log(2) // in thread 3` `console.log(3) // in thread 2` `console.log(4); console.log(5); // in thread 1` to be executed in a chronological order. – viz Dec 15 '17 at 06:35
  • Thank you. You are so great! – Xu Young Dec 15 '17 at 07:09
0

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.

Fabiano
  • 1,344
  • 9
  • 24
0

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()
Nic Olas
  • 451
  • 2
  • 10
0

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)
})
HMR
  • 37,593
  • 24
  • 91
  • 160