So, this concept I’ve actually been using for a while but unknowingly. An example of this is the .fetch() method and .then().
It makes API use very, very easy!
Example:
fetch('https://nodestarter-prod.herokuapp.com/api/all/data',{
headers : {
'method': 'GET',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then((res) => res.json())
.then((data) => console.log(data) );
But, let’s take a look at how we can actually do async functions because Ive definitely been a perpetrator of callback hell!!!
First, we need to understand Promises…
Example code we will walkthrough:
// doWork is a reg func that takes 2 parameters (resolve) and (reject)
//after a delay of 5 seconds, resolve is called with the value "done"
const doWork = (res, rej) => {
setTimeout(() => {
res("TIMEOUT DONE");
}, 5000);
};
// someText is the promise for the doWork function
// we await the response of the doWork function
let someText = new Promise(doWork);
//once the promise is resolved, we log the response
someText.then((val) => {
console.log(`Log 1: ${val}`); // Log 1: Done
});
So, simply we have a function with a 5-second timer and the ‘res’ parameter we set to “TIMEOUT DONE”.
Then we have a variable that is a promise object that waits for the doWork function to finish.
We then add a function to the result (console.log), but of course we can do whatever we want here.
So that’s what is happening, but not why!
This is where I must defer you to this resource: https://www.udemy.com/course/understand-javascript/
This is the best place to learn web dev stuff as it fits nicely what a mentor taught me:
“nothing is ever complicated”
Anyhow back to the topic:
In the course video, it’s described as (please ignore the beginner oversimplification and if misunderstandings).
What kind of happens
This way JS is still ‘single-threaded’ & ‘non-blocking’.
remember async await is just ‘sugar’ for the promise method, it is literally the same thing.
basic async example:
//async functions
async function funcName() {
console.log("funcName:" + funcName.name);
await funcName2();
}
function funcName2() {
setTimeout(() => {
console.log("funcName2");
}, 5000);
}
funcName();
Now you can start to see how we can swap out the time out function for any other request i.e. .fetch() or db.query()
So, a better fetch example using async is:
//async functions
async function funcName() {
await funcName2().then((data) => console.log(data));
}
function funcName2() {
return data = fetch("https://nodestarter-prod.herokuapp.com/api/all/data", {
headers: {
"Method": "GET",
"Content-Type": "application/json",
"Accept": "application/json"
},
}).then((res) => res.json());
}
funcName();
In the browser, you could easily trigger the funcName(); on click event listener.
The approach above clearly breaks out the 3 operations
F|finally, it’s so easy to read and understand what is actually the intended process here, rather than getting confused by syntax.
An alternate way of using async/await that is probably cleaner again:
//async functions
async function funcName() {
const response = await fetch("https://nodestarter-prod.herokuapp.com/api/all/data", {
headers: {
"method": "GET",
"Content-Type": "application/json",
"Accept": "application/json",
"Access-Control-Allow-Origin": ""
},
}).then((res) => res.json());
console.table(response)
}
funcName();
How to condense further:
const api = {
baseURL:'https://nodestarter-prod.herokuapp.com/api/all/data',
meta: {
headers: {
"Method": "GET",
"Content-Type": "application/json",
"Accept": "application/json",
"Access-Control-Allow-Origin": ""
}
}
}
onGetAPIData = async () => {
const response = await fetch(`${api.baseURL}`, api.meta).then((res) => res.json())
console.log(response[0].id);
}
onGetAPIData();
As you can see the api method is just 4 lines by moving the variables to an object!