바보린
바보린

Reputation: 179

I have a question about js Async Await behavior structure

function delay(count) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve(1000);
    }, count);
  });
}
async function method1() {
  let val = 0;
  console.log("one");
  val = delay(3000);
  console.log("two")
  return val;
}
method1().then(function(result) {
  console.log(result);
});

Above is my example code.
First of all, I didn't use await delay() and this is what I intended.
First, the expected flow of writing the above code is as follows:

  1. console.log("one")
  2. console.log("two")
  3. return val;
  4. console.log(result)
  5. resolve(1000);

But the reality was different. The actual execution result is as follows.

  1. console.log("one")
  2. console.log("two")
  3. resolve(1000)
  4. return val;
  5. console.log(result)

The reason I expected return val to be executed first is because This is because we believed that the rest of the code would be executed while the delay() function proceeded with asynchronous communication. However, in reality, the return is not performed until delay() is finished.

If I use await delay() Pause at delay(). After that setTimeout exits,console.log("two") is executed and I fully understand this concept .
However, if await is not used, the rest of the code is executed, but why is the return not executed until delay() is finished?

Upvotes: 2

Views: 89

Answers (2)

Yousaf
Yousaf

Reputation: 29282

The actual execution result is as follows.

1. console.log("one")
2. console.log("two")
3. resolve(1000)
4. return val;
5. console.log(result)

No, that's not the correct execution order. Step 4 will happen before step 3.

Your code is executed as:

  1. Call method1

    1. declare val and initialize it to 0

    2. log "one"

    3. call delay function

      1. create a new promise
      2. call setTimeout and schedule a callback function
      3. return the newly created promise from the delay function
    4. Assign the return value of delay function to val

    5. log "two"

    6. return val from method1

  2. Call then() method on the promise returned by the method1

  3. Script end

Now After some time, timer fires, resolving the promise returned by the method1 which then invokes the callback function passed to the then() method.

However, if await is not used, the rest of the code is executed, but why is the return not executed until delay() is finished?

method1 returns only after delay function is finished executing. delay function returns a promise which is then assigned to the val variable. All of this happens synchronously.

Execution of the delay function is finished before the timer fires and the promise is resolved.

Upvotes: 1

brk
brk

Reputation: 50291

This is because we believed that the rest of the code would be executed while the delay() function proceeded

Your code is equivalent to this. You are assigning a promise to val. Since val is a Promise so you are able to use then and after 3000ms when it resolves, it logs the value inside then

async function method1() {
  let val = 0;
  console.log("one");
  val = new Promise(function(resolve) {
    setTimeout(function() {
      resolve(1000);
    }, 3000);
  });
  console.log("two")
  return val;
}
method1().then(function(result) {
  console.log('**', result);
});

From Comment

As far as I know a promise is simply a piece of code that runs when a certain action completes.

Promises are eagerly loaded. The constructor will not return until the executor has completed. When executor obtains a result , it calls one of the function resolve or reject. So it is not a piece of code that runs when a certain action completes

In the below example you can see Promise is executing as soon as it is assigned to the variable

async function method1() {
  let val = 0;
  console.log("one");
  val = new Promise(function(resolve) {
    setTimeout(function() {
      console.log('Inside Promise')
      resolve(1000);
    }, 3000);
  });
  console.log("two")
  return val;
}
method1()

Upvotes: 2

Related Questions