OverView of async/await
Targets of this article
- People who know "Promise" of JavaScript.
- People who want to know better way of writing async function than "Promise".
My experiences of "async/await"
I like "Promises" of JavaScript because we can write async function without Callback-Hell.
What if there is better writing style of async functions? That is async/await
. Before I knew async/await
, I had always used "Promises". But now, I prefer async/await
to Promises
. The reason why I prefer async/await
is that we can write async functions as if syncronous functions. It is much readable and organized.
Why should we know this?
As I already told you, async/await
allows us to write async functions that looks like syncronous style.
I prepared example code below that is written Promises
style and async/await
style. Let's have a look.
// ### Promises style ### function getFileDataByPromises() { return Promise.all([ readFile('/path/to/file1.json'), readFile('/path/to/file2.json'), readFile('/path/to/file3.json'), ]).then(results => { const data1 = results[0]; const data2 = results[1]; const data3 = results[2]; return buildDataWithFiles(data1, data2, data3); }).catch(err => { throw err; }); } // ### async/await style ### async function getFileDataByAsyncAwait() { const data1 = await readFile('/path/to/file1.json'); const data2 = await readFile('/path/to/file2.json'); const data3 = await readFile('/path/to/file3.json'); try { return buildDataWithFiles(file1, file2, file3); } catch(err) { throw err; } } // ### Helper functions const fs = require('fs'); function readFile(filePath) { return new Promise((resolve, reject) => { fs.readFile(filePath, 'utf-8', (err, data) => { if(err) { reject(err); } resolve(data); }); }); } function buildDataWithFiles(data1, data2, data3) { const buildData = []; // Something that combines file1, file2 and file3 // ... return buildData; }
How do you feel above code? Even though Promises
pattern looks good in comparison to Callback-Hell pattern, async/await
looks much better at least I think. In Promises
, we have to pass result data via then
method. If you want to add one more then
method and pass first result of Promises again, You should write it like below.
function getFileDataByPromises() { let data1, data2, data3; return Promise.all([ readFile('/path/to/file1.json'), readFile('/path/to/file2.json'), readFile('/path/to/file3.json'), ]).then(results => { data1 = results[0]; data2 = results[1]; data3 = results[2]; return buildDataWithFiles(data1, data2, data3); }).then(builtData => { // something process with data1, data2 and data3. // ... }).catch(err => { throw err; }); }
In above example code, values are assigned to the empty variables(data1, data2 and data3). This means that this code potentially have bugs because values are mutable and It is possible that values might not be our expected value.
On the other hand, async/await
style is much organized and stylish. We don't have to difine empty variable, which means we can use const
declaration. We can avoid unnecessary updating values and bug generated by update.
How to use async/await
Syntax
async function asyncFunction() { const resultOfPromise = await somethingProcessWithPromise(); }
From MDN page of await.
The await operator is used to wait for a Promise. It can only be used inside an async function.
- You can use
await
statement in functions withasync
declaration beforefunction
declaration. - When you put
await
operator before calling function, the function should return "promise" object.
Let's see the below image of example code. I wll explain what this code does after the image.
Example code
- Preparing functions.
- async function asyncFunction() {...}
- A function that use
async/await
- A function that use
- function somethingProcessWithPromise(){...}
- A function that returns promise object.
- async function asyncFunction() {...}
- Calling asyncFunction()
- Inside asyncFunction, I use
await
operator before"somethingProcessWithPromise()"
that returns promise object. resultOfPromise
variable will be assigned value whenresolve
ofpromise
is executed.- In this case
resultOfPromise
should be 'Hello!' becauseresolve
function takes 'Hello' as a argument.
- In this case
console.log
is not exuecuted until the value is assigned toresultOfPromise
variable.resolve
is executed after 1000 milliseconds with setTimeout.
- Inside asyncFunction, I use
- 'Hello!', 'Hi!' is output on the log.
Conclusion
- We can write async functions as if syncronous functions.
- To use
async/await
, we need to putasync
operator before function name andawait
operator before executing a function that returns promise object. await
operator can be inside only functions that is usedasync
operator.