Zum Hauptinhalt springen

Js async

  • quick lookup for js implementations for when i need them

Callback Function

  • function that is performed after another function has completed.
//html
<button class="clickMe">Click Me</button>

//js
const btn = document.querySelector(".clickMe");

// implementation without a callback:
function wasClicked(){
console.log("was clicked")
}
btn.addEventListener("click", wasClicked)

// implementation with a callback:
btn.addEventListener("click", () => {
console.log("was clicked")
})

Promises in JS

  • cleaner way to write asynchronous code
  • a promise is an object that returns a value that you expect/hope to see in the future, but have no access to at the moment (HTTP-request, userimput, API-call ....).
  • There are 3 states of the Promise object:
    • Pending: initial state
    • Resolved: completed the promise
    • Rejected: failed to complete the promise
// example stacking callbacks the BAD! way:
setTimeout(() => {
console.log("loading stuff took 5 Seconds...")
setTimeout(() => {
console.log("done stuff for 3 more Seconds..")
setTimeout(() => {
console.log("it took 2 seconds to prepare, finishing in 1 more.")
setTimeout(() => {
console.log("finally done with everything!")
}, 1000)
}, 1000)
}, 3000)
}, 5000)
  • basic structure:
const promise = new Promise((resolve, reject) => {
let condition

if(condition){
resolve("Promise was successfully")
} else {
reject("Promise is rejected")
}
})
  • rewrite example
function addToQueue(timeItTakes, todo){
return new Promise((resolve, reject) => {
if(todo){
setTimeout(() => {
console.log(todo)
resolve()
}, timeItTakes)
} else {
reject("cant do nothing")
}
})
}


addToQueue(5000, "loading stuff took 5 Seconds...")
.then(response => addToQueue(3000, "done stuff for 3 more Seconds.."))
.then(res => addToQueue(2000, "it took 2 seconds to prepare, finishing in 1 more."))
.then(res => addToQueue(1000, "finally done with everything!"))
.catch(err => console.log(err)) // will catch errors in any of the above promises
  • example of fetching some Data
const promise = fetch("https://getweather.com/api/location=leipzig")

promise
.then(res => res.json())
.then(data => console.log(`weather in Leipzig is ${data.description} and Temperature is ${data.temp.celsius}°C`))
.catch(err => console.error(err))

fetch request - GET request

  • small working fetch request
fetch("https://type.fit/api/quotes")
.then((response) => response.json())
.then((data) => console.log(data))
.catch((err) => console.log(err));
  • the above will not catch HTTP errors such as 400, since we will get a "response", so we add the res.ok check
fetch("https://type.fit/api/quotes")
.then(response =>{
if(!respone.ok) throw Error(response.statusText)
return response.json()
})
.then((data) => console.log(data))
.catch((err) => console.log(err));

async

  • allows to write asynchronous code in a more human style compared to promises
  • all we have to do is write the word async before a function and it returns a promise of whatever return value it had before
  • try{} catch{} finally {} for error handling

// the above fetch-request rewritten:
const fetchData = async () => {
try {
const quotes = await fetch("https://type.fit/api/quotes")
const response = await quotes.json()
console.log(response)
} catch (error) console.log(error)
}
fetchData()

await

  • the await makes JS wait untill a promise setlles and returns its result
function delay() {
let time = Math.random()*3000
setTimeout(function() {
//your code to be executed after 1 second
}, time)
return time/1000
}

async function fetchJuice(name){
const table = {
orange: "orange-juice",
peach: "peach-juice",
strawberry: "strawberry-juice",
}
let time = await delay()

console.log("fetched: "+table[name]+ `in ${time} seconds`)
return table[name]
}
fetchJuice("strawberry").then(console.log)

const mixJuices = async() => {
const juice1 = fetchJuice("orange")
const juice2 = fetchJuice("peach")
const mix = await Promise.all([juice1, juice2]) //this will wait for all the promises of the fetchJuice juices to resolve
return mix
}
mixJuices().then(console.log)
// additional to iterate
const fruit = ["peach", "orange", "strawberry"]

const fruitLoop = async() =>{
for await (let flavor of fruit){ console.log(flavor)}
}

const fruitInspection = async () =>{
if (await getFruit("peach") === "peach-juice"){
console.log("real peach")
}
}

POST request

// fill our data we want to post
const update = {
title: "blogpost by vincepr",
body: "the most brilliant essay to ever be written...",
userId: 123,
}

// get Post-request format ready
const options = {
method: "POST",
headers: {
"Concent-Type": "appliaction/json",
},
body: JSON.stringify(update),
}

// communicate with the api
fetch("https://someblog.com/api/posts", options)
.then(data => {
if(!data.ok) throw Error(data.status)
return data.json()
})
.then(update => {
console.log(update)
//show new blog on the ui etc...
})
.catch(err => console.error(err))
  • notice endpoints may change with time and API's may be restructured. So put all your fetch calls together for easier access.