How does javascript async/await actually work?
You have to read the quoted part slightly differently:
An async function can contain an await expression that pauses the execution of the async function
Just the async function itself pauses execution, the function that called it goes on then.
If you think of a synchronous callstack, what happens is that the asynchronous functions context gets popped of, and stored somewhere else:
stack: [init] -> [async] fun1 -> sleep -> setTimeout
// The promise gets returned from sleep
stack: [init] -> [async] fun1
// The async function gets popped of
stack: [init]
hidden: [async] fun1
// synchronous execution ends
stack: -
hidden: [async] fun1
// the timer triggers, the promise gets resolved
stack: setTimeout callback
hidden: [async] fun1
// synchronous execution ends
stack: -
hidden: [async] fun1
// the promise resolves, the async fun1 context gets moved onto the stack
stack: [async] fun1
It seems fun1 returns at the "await" line
Yes, exactly. In that moment it returns a promise, that resolves when the async function returns (after it continued execution somewhen).
And it seems I never get the return value of fun1("returnfromfun1").
You can get it when the promise resolves:
fun1().then(result => console.log(result));
Why is async required to call await inside a JavaScript function body?
There are three reasons the async
keyword exists:
In ECMAScript language versions prior to 2015,
await
was not a keyword. Marking a functionasync
provides a syntactic "bailout" to indicate a breaking change in the language grammar within the body of the function.This is the most important reason. Without the
async
keyword, all programs written in ECMAScript 5 or older would no longer work if they used theawait
keyword as a variable (in fact this was done intentionally in some cases as a polyfill beforeasync
/await
was standardized), since that would cause a breaking change without the addition ofasync
to the specification. Because of this,async
is syntactically necessary to avoid breaking changes to the language.It provides a convenient marker for parsers, avoiding an infinite look-ahead in order to determine whether or not a function is asynchronous.
This makes parsing more efficient, which is appealing for both ECMAScript implementers and developers, though this reason alone does not make
async
strictly necessary to the syntax.async
also performs its own transformation on the function, which is done regardless of whether or not theawait
keyword is present in the body.Consider the following two functions:
function foo() {
if (Math.random() < 0.5) {
return 'return';
} else {
throw 'throw';
}
}
async function bar() {
if (Math.random() < 0.5) {
return 'return';
} else {
throw 'throw';
}
}async
performs the following transformation offunction bar()
:function bar() {
return new Promise((resolve, reject) => {
try {
resolve((/*async function bar*/() => {
if (Math.random() < 0.5) {
return 'return';
} else {
throw 'throw';
}
})());
} catch (reason) {
reject(reason);
}
});
}Those familiar with promises will recognize that we can simplify the above since the Promise constructor executor function will implicitly reject if it throws an error synchronously:
function bar() {
return new Promise((resolve) => {
if (Math.random() < 0.5) {
return resolve('return');
} else {
throw 'throw';
}
});
}
Asynchronous Javascript Confusion
The key thing to understand is that async
functions are syntactic sugar for using promises. Neither async
functions nor promises make anything happen in the background. They let you wait for and react to things that already happen in the background (like a timer or an HTTP operation completing).
An async
function is synchronous up until the first await
or return
. (That's so it can start whatever asynchronous process it then waits for.) At that point, it returns a promise that will be fulfilled or rejected depending on what happens to the promise being await
ed and/or what you return.
await
pauses the logic of the function until/unless the promise being await
ed settles. (If you use await value
where value
isn't a thenable [a promise-like thing], you're effectively doing await Promise.resolve(value)
.)
You haven't shown any contents of the asyncFuncX
functions, but unless they await
something, they're fully synchronous.
You may find my answer from a couple of days ago useful as well.
What are the advantages of using async/await?
It can be considered to be not actually synchronous. When you await
something that is async
, it gets added to a microtask queue. It does not run on the main thread, meaning other things can occur (click events, rendering, etc.)
Here is a fantastic talk that can explain it in further detail
https://www.youtube.com/watch?v=cCOL7MC4Pl0
await/async
are often referred to as syntactic sugar, and let us wait for something (e.g. an API call), giving us the illusion that it is synchronous.
Related Topics
Sorting a JSON Object in JavaScript
Getting Title from Wkwebview Using Evaluatejavascript
Most Efficient Method of Detecting/Monitoring Dom Changes
How to Create an Object from an Array of Key-Value Pairs
Template Literal Inside of the Regex
Triggering Onclick Event Using Middle Click
JavaScript Read File Without Using Input
"Cannot Use Import Statement Outside a Module" Error When Importing React-Hook-Mousetrap in Next.Js
How Would You Overload the [] Operator in JavaScript
Simple Component Is Not Rendering: React Js
How to Use Ranges in a Switch Case Statement Using JavaScript
Check If One Date Is Between Two Dates
How to Include Js.Erb File in View Folder