Understanding async/await on NodeJS
Solution 1
To clear a few doubts -
- You can use
await
with any function which returns a promise. The function you're awaiting doesn't need to beasync
necessarily. - You should use
async
functions when you want to use theawait
keyword inside that function. If you're not gonna be using theawait
keyword inside a function then you don't need to make that functionasync
. -
async
functions by default return a promise. That is the reason that you're able toawait
async
functions.
From MDN -
When an async function is called, it returns a Promise.
As far as your code is concerned, it could be written like this -
const getUsers = (ms) => { // No need to make this async
return new Promise(resolve => setTimeout(resolve, ms));
};
// this function is async as we need to use await inside it
export const index = async (req, res) => {
await getUsers(5000);
res.json([
{
id: 1,
name: 'John Doe',
},
{ id: 2,
name: 'Jane Doe',
},
]);
};
Solution 2
Async functions in Javascript
The async
keyword turns a regular JS function declaration into an asynchronous function declaration:
function syncFunc {// dostuff}
async function asyncFunc {// dostuff} // the async keyword is placed before the function keyword
An async function returns a Promise:
- When the async function returns a value, the Promise will be resolved with the returned value.
- When the async function throws an exception or some value, the Promise will be rejected with the thrown value.
Inside an async function you can use the await
keyword. await
placed before a promise causes the async function to pause until the promise is settled (either rejected or fulfilled)
- . When the promise fullfills The value of the
await
expression is the value of the fullfilled promise. - When the promise is rejected the
await
expression throws the rejected value.
Example:
function makePromise(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 1000);
});
}
async function asyncFunc() {
var x = await makePromise(1); // the function is paused here until the promise is fulfilled
console.log(x); // logs 1
return x;
}
const returnedProm = asyncFunc(); // the async func returns a promise
returnedProm.then((x) => console.log(x));
// This promise is fulfilled with the return value from the async func, so this logs 1
When to use asynchronous functions:
Async functions are a useful tool when you have multiple asynchronous actions (implemented as promises) which depend on each other. For example when your second promise needs data that your first promise will provide. You now can conveniently use the await
keyword to first receive the data in promise 1, and then pass this data as an argument to promise 2.
In other words, async function can via the await
keyword make asynchronous programming behave like synchronous programming. As a consequence your applications are easier to understand.
Solution 3
You can await
any promise in an async
function. The code after the await
will be executed after the promise that you are awaiting finished.
This is a great alternative to classic JavaScript callbacks.
I wrote a blog about it -> https://github.com/Gameye/js-async I hope this will help you!
Solution 4
async await are just syntactic sugar for promises.
you use them like you use promises when you want your code to run on complete of a function.
async function asyncOperation(callback) {
const response = await asyncStep1();
return await asyncStep2(response);
}
is the exact thing if you used promises land syntax:
function asyncOperation() {
return asyncStep1(...)
.then(asyncStep2(...));
}
The new async/await syntax allows you to still use Promises, but it eliminates the need for providing a callback to the chained then() methods.
The callback is instead returned directly from the asynchronous function, just as if it were a synchronous blocking function.
let value = await myPromisifiedFunction();
When you are planning to use await in your function you should mark your function with async keyword (like in c#)
You don't have to create your getUsers as anonymous function.
Related videos on Youtube
Christopher Francisco
Updated on September 14, 2022Comments
-
Christopher Francisco over 1 year
I think my understanding of it might be affected by my experience with .NET's
async/await
, so I'd like some code example:I'm trying to make a express controller wait 5 seconds before returning the response:
const getUsers = async (ms) => { var wait = ms => new Promise(resolve => setTimeout(resolve, ms)); await wait(ms); }; export const index = (req, res) => { async () => { await getUsers(5000); res.json([ { id: 1, name: 'John Doe', }, { id: 2, name: 'Jane Doe', }, ]); }; };
This code doesn't work, the browser keeps loading and loading and never shows a thing.
The
getUser
function I built based on this SO answer, and the controller method, based on my (mistaken) understanding of how it works so I'd like some clarification and correction:1. when should I use
await
?To my understanding, you should use
await
before anasync
function call. Is this correct? Also, why can I call await before a non-async function that returns a promise?2. When should I use
async
?To my understanding, you mark a function as an
async
one so that it can be called with theawait
keyword. Is this correct? Also, [why] do I have to wrap myawait getUsers(5000)
call in an anonymous async function?-
Joel Harkes almost 7 yearsDon't wrap stuff inside an async anonymous function, which in your code also is never executed. Instead make the index function async and remove the function wrap and return res.json
-
-
Christopher Francisco almost 7 yearsThis explanation is very clear. Now, the rest is just hook up the exported async function
index
(which is a function that returns a promise) with the express router, with onerouter.get
variation that accepts a promise. Is this correct? -
Jyotman Singh almost 7 yearsYes in Express you could use it like this -
router.get('/users', index)
. -
hatef about 3 yearsNicely put: In other words, async function can via the await keyword make asynchronous programming behave like synchronous programming. As a consequence your applications are easier to understand.