2. Async JS
Async JS
The call stack
- Mechanism that JS uses to keep track where it is in a script. Last thing in, first thing out.
- To see the call stack in action use Sources in Chrome
Web API and Single Threaded
- http://latentflip.com/loupe
- JS is single threaded
- The browser come with web API that can handle tasks in background
- setTimeout is a web api function (-> callback function)
- callback is used to delay execution
Promises
- Objects that represents the eventual completion or failure of an asynchronous operation
- Attach callback to the promise instead of passing them into a function
const request = dummyReqPromise('google.com/api')
request.then( (data) => {
console.log('PROMISE 1 RESOLVED')
console.log(data)
})
.then( (data) => {
console.log('PROMISE 2 RESOLVED')
})
.then( (data) => {
console.log('PROMISE 3 RESOLVED')
})
.catch( (err) => {
console.log('PROMISED REJECTED')
console.log(err)
})
Creating promises
const fakeRequest = (url) =>{
return new Promise((resolve, reject)=>{
setTimeout(() => {
resolve('something');
}, 1000);
})
}
fakeRequest('/cats/1')
.then( (data) => {
console.log("Done with request")
console.log(data)
})
Async Function
- async functions always return a promise
const asyncFunction = async () => {
//returns a promise
return 'aaaa' //resolved value
}
- to reject a promise: throw an error
const asyncFunction = async () => { throw 'random error' }
- login example ```chsarp const login = async (username, password) => { if (!username || !password) throw ‘Missing Credentials’ if (password === ‘1234’) return ‘Welcome’ throw ‘Invalid Password’; }
login(‘aaa’, ‘1234’) .then(msg => { console.log(‘logged in’); console.log(msg); }) .catch(err =>{ console.log(“error”) console.log(err) })
### Await keyword
- wait for a promise to be resolved before continuing with the async function
```csharp
const changeBackColor = (color, delay) =>{
return new Promise((resolve, reject) =>{
setTimeout( () => {
document.body.style.backgroundColor = color;
resolve();
}, delay)
}
)
}
async function rainbow(){
await changeBackColor('red', 1000)
await changeBackColor('blue', 1000)
await changeBackColor('green', 1000)
}
Rejected Promised
const fakeRequest = (url) =>{
return new Promise((resolve, reject) => {
const delay = Math.floor(Math.random() * 4500)+500;
setTimeout(() => {
if (delay > 4000) {
reject ('connection timeout')
}
else{
resolve (`here is your data ${url}`)
}
}, delay);
})
}
async function makeTwoRequests(){
try{
let data1 = await fakeRequest('/apple1')
console.log(data1)
let data2 = await fakeRequest('/apple2')
console.log(data2)
}
catch(e){
console.log('error is', e);
}
}
AsyncJavascriptAndXml requests
- make request after the page has been loaded
- jsonformatter.curiousconcept.com
- JSON.parse(data) converts a string into json object
Fetch API
- fetch returns a promise:
fetch('https://api.google.com')
.then(res => {
console.log("RESPONSE", res)
return res.json();
})
.then( data => {
console.log(data.ticker.price);
})
.catch(e => {
console.log('error');
})
- using async function:
const fetchBitcoinPrice = async () => {
try{
const res = await fetch('https://api.google.com');
const data = await res.json();
console.log(data.ticker.price);
}
catch(e){
console.log(e);
}
}
Axios
- easier than use fetch
axios.get('https://api.cryptonator.com/api/ticker/btc-usd')
.then( res => {
console.log(res.data.ticker.price);
})
.catch( err => {
console.log("Error", err);
})
const fetchBTCPrice = async () => {
try{
const res = await axios.get('https://api.cryptonator.com/api/ticker/btc-usd');
console.log(res.data.ticker.price);
}
catch (e) {
console.log("Error", e);
}
}
Setting Headers
- set headers to get desired response type (html, json…)
const getDadJoke = async () => {
const config = {headers:{Accept: 'application/json'}}
const res = await axios.get('https://icanhazdadjoke.com/', config);
return res.data.joke;
}
const jokeBtn = document.querySelector('#jokeBtn')
const jokeText = document.querySelector('#jokeText')
jokeBtn.addEventListener('click', async () => {
try{
await console.log('clicked')
await getDadJoke().then(res => {
jokeText.textContent = res;
});
}
catch(err){
jokeText.textContent = "Error joke not available";
}
})
Written on April 1, 2021