Sandeep Sudhakaran
Sandeep Sudhakaran

Reputation: 1092

How async/await and Promise work in TypeScript

I have a small function to learn how async,await and promise workes here.

function delay(ms: number) {
    return new Promise<void>(function(resolve) {
       setTimeout(resolve, ms);
    });
}

async function asyncAwait() {
    console.log("A");

    await delay(1000);
    console.log("B");

    await delay(1000);
    console.log("C");
}

asyncAwait();
console.log("D");

My understanding , the workflow would be like,

call asyncAwait(); first, then print A, then wait for 1s and print B then wait for another 1s and print C at last print D.

but my output is like,

A
D
B
C

I don't know why console.log("D") is displaying second.

can anyone explain the above code ?

thanks in advance

Upvotes: 2

Views: 5152

Answers (3)

Abhyudit Jain
Abhyudit Jain

Reputation: 3748

It is how asynchronous calls work.

What you think the code execution is like:

function delay(ms: number) {
    return new Promise<void>(function(resolve) {
       setTimeout(resolve, ms);
    });
}

async function asyncAwait() {
    console.log("A");

    await delay(1000);
    console.log("B");

    await delay(1000);
    console.log("C");
}

asyncAwait();   // <-- 1st call
console.log("D");

Then inside that function:

async function asyncAwait() {
    console.log("A");  // <--- 1st print, as it is synchronous

    await delay(1000); // <--- await
    console.log("B");  // <--- 2nd print

    await delay(1000); // <-- await
    console.log("C");  // <-- 3rd print
}

And then finally

function delay(ms: number) {
    return new Promise<void>(function(resolve) {
       setTimeout(resolve, ms);
    });
}

async function asyncAwait() {
    console.log("A");

    await delay(1000);
    console.log("B");

    await delay(1000);
    console.log("C");
}

asyncAwait();
console.log("D"); // <-- last print

BUT, the async function is asynchronous. So all the async calls go into the queue and are processed later.

Hence, first the synchronous calls are executed:

console.log("A");
console.log("D");

And then the async calls.

The await only works inside an async function.

So the function:

async function asyncFunc() {
  console.log("A");

  await delay(1000);
  console.log("B");
}

is roughly equivalent to this:

asyncFunc() {
  console.log('A');
  delay().then(()=> {
     console.log('B');
  });
}

So if you want the console.log("D") to be executed after the async function you should await the asyncFunction. But to use await, you have to be in a async function:

async function asyncFunc2() {
  await asyncAwait();
  console.log("D");
}

asyncFunc2();

Upvotes: 3

Daniel San
Daniel San

Reputation: 2026

It's behaving like that because under the hood, your code is this:

function equivalentFunction() {
    console.log("A");
    setTimeout(
        function() {
            console.log("B");
            setTimeout(
                function() {
                    console.log("C");
                }
            ,1000)
        }
    ,1000)
}

equivalentFunction();
console.log("D");

Upvotes: 1

Nenad
Nenad

Reputation: 26647

You have to await for asyncAwait() call:


function delay(ms: number) {
    return new Promise<void>(function(resolve) {
       setTimeout(resolve, ms);
    });
}

async function asyncAwait() {
    console.log("A");

    await delay(1000);
    console.log("B");

    await delay(1000);
    console.log("C");
}

async function main() {
    await asyncAwait();
    console.log("D");
}

main();

Upvotes: 2

Related Questions