Just going through this tutorial, and it baffles me to understand why await
only works in async
function.
From the tutorial:
As said, await only works inside async function.
From my understanding, async
wraps the function return object into a Promise, so the caller can use .then()
async function f() { return 1; } f().then(alert); // 1
And await
just waits for the promise to settle within the async
function.
async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("done!"), 1000) }); let result = await promise; // wait till the promise resolves (*) alert(result); // "done!" } f();
It seems to me their usage are not related, could someone please explain?
The "await is only valid in async functions" error occurs when the await keyword is used inside of a function that wasn't marked as async . To use the await keyword inside of a function, mark the directly enclosing function as async .
The await operator is used to wait for a Promise . It can only be used inside an async function within regular JavaScript code; however it can be used on its own with JavaScript modules.
You can not use the await keyword in a regular, non-async function. JavaScript engine will throw a syntax error if you try doing so. function caller() { // Using await in a non-async function. const user = await fetchUserDetails(); } // This will result in an syntax error caller();
Why does "await" always need an "async" ? This is because if you were able to put await in synchronous code, you would block the (main) thread. This was already possible to do before async and await keywords. You can simply resolve a promise.
await
- we wouldn't know what to returnWhat await
does in addition to waiting for the promise to resolve is that it immediately returns the code execution to the caller. All code inside the function after await
is asynchronous.
async
is syntatic sugar for returning a promise.await
, what would be the sane alternative in an asynchronous code?Let's look at the following erroneous code to see the problem of the return value:
function f() { // Execution becomes asynchronous after the next line, what do we want to return to the caller? let result = await myPromise; // No point returning string in async code since the caller has already moved forward. return "function finished"; }
We could instead ask another question: why don't we have a synchronous version of await
that wouldn't change the code to asynchronous?
My take on that is that for many good reasons making asynchronous code synchronous has been made difficult by design. For example, it would make it too easy for people to accidentally make their whole application to freeze when waiting for an asynchronous function to return.
To further illustrate the runtime order with async
and await
:
async function f() { for(var i = 0; i < 1000000; i++); // create some synchronous delay let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("done!"), 1000) }); console.log("message inside f before returning, still synchronous, i = " + i); // let's await and at the same time return the promise to the caller let result = await promise; console.log("message inside f after await, asynchronous now"); console.log(result); // "done!" return "function finished"; } let myresult = f(); console.log("message outside f, immediately after calling f");
The console log output is:
message inside f before returning, still synchronous, i = 1000000 message message outside f, immediately after calling f message inside f after await, asynchronous now done!
async
and await
are both meta keywords that allow asynchronous code to be written in a way that looks synchronous. An async
function tells the compiler ahead of time that the function will be returning a Promise
and will not have a value resolved right away. To use await
and not block the thread async
must be used.
async function f() { return await fetch('/api/endpoint'); }
is equivalent to
function f() { return new Promise((resolve,reject) => { return fetch('/api/endpoint') .then(resolve); }); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With