How Async Await Works

Async

async is basically a syntatic sugar of promise, consider the following code

async function foo(name) {
  console.log(name, "start");
  console.log(name, "middle");
  console.log(name, "end");
}

Which is essentially the same as

function foo(name) {
  return new Promise((resolve) => {
    console.log(name, "start");
    console.log(name, "middle");
    console.log(name, "end");
    resolve();
  });
}

even when you call

console.log("1")
foo("First");
console.log("2")

the javascript will execute these line by line anyways. So the call stack is as following:

[
	console.log("1"),
	console.log("first", "start"),
	console.log("first", "middle"),
	console.log("first", "end"),
	console.log("2"),
]

Await

await will pause the execution of the current async function until the promises is settled. It will then resolve the promise for us.

Consider the following:

async function foo(name) {
  console.log(name, "start");
  await console.log(name, "middle");
  console.log(name, "end");
}

Which in Promise way, equivalent to

function foo(name) {
	return new Promise(resolve => {
		console.log(name, "start")
		resolve(console.log(name, "middle"))
	}).then(() => console.log(name, "end"))
}

Pausing in here means that await will put the next function in the bottom of the stack and execute what it can first. As a result, it will put

console.log(name, "end") 

in the bottom of the stack

So if we have something like

console.log("1")
foo("First");
console.log("2")

The call stack will be

[
	console.log("1")
	console.log("First", "start")
	console.log("First", "middle")
	// put console.log("First", "end") bottom of the stack
	console.log("2")
	console.log("First", "end")
]

Note: it's still single thread here, it just delay the result to the bottom to execute the other thing first.