Promises - Fetch

JS

Waarom asynchroon?

Promises

  • JavaScript is single-threaded

  • Sommige taken duren lang (API ophalen, bestanden, timers)

  • De pagina mag niet blokkeren

Probleem

console.log("Code voor");


// hier stuk code dat lang duurt
// ... fetch("https://api.example.com/data") ...
//


console.log("Code na");
document.body.style.backgroundColor = "red";

"Promises"

Voordeel

  • Wachten op iets dat later klaar is

  • Geen blokkerende code

  • Mogelijkheid tot foutafhandeling

Oplossing

  • Je kan in JavaScript zelf een promise aanmaken, maar dat is al redelijk advanced en niet zo vaak nodig
  • Wel heel vaak nodig: het ophalen van data. Deze promise zit standaard in JavaScript: fetch

Promises

Fetch

Promises

  • Browserfunctie

  • Haalt data op via URL

  • Geeft een Promise terug

Wat is fetch?

fetch("https://api.example.com/data");
  • Het antwoord (response) moet omgezet worden naar JSON

  • Dataformaat

  • Lijkt op een JavaScript object

  • Wordt door bijna alle moderne API’s gebruikt

JSON

{
  "id": 1,
  "title": "Hallo wereld"
}

Optie 1: then

Hoe promise gebruiken?

  • Wacht op het resultaat

  • Voert functie uit als de promise fulfilled is

  • Probleem? Catch

Then

const url = "https://www.pgm.gent/data/emojis/emojis.json";

fetch(url)
  .then(res => res.json())
  .then(data => {
        // hier alle code die we willen uitvoeren 
        // indien fetch gelukt is
        console.log(data);
   })
  .catch(err => console.error("Fout:", err));

Pro

  • Gemakkelijk te gebruiken

Con

  • Veel indenting / nesting
  • Moeilijker te lezen

 

Pro/Con

fetch("https://www.pgm.gent/data/emojis/emojis.json")
  .then(res => res.json())
  .then(data => {
        // hier alle code die we willen uitvoeren indien fetch gelukt is
        console.log(data);
   })
  .catch(err => console.error("Fout:", err));

Optie 2: async / await

Hoe promise gebruiken?

  • Nieuwere manier van async code

  • Ziet eruit als “gewone” code

  • await werkt alleen in een async functie

Async / Await

async function loadData() {
  const url = "https://www.pgm.gent/data/emojis/emojis.json";
  const response = await fetch(url);
  const data = await response.json();
  console.log(data);
}
loadData();

Let op: dit is nog steeds dezelfde fetch functie als in optie 1! We gebruiken deze gewoon op een andere manier

  • Nieuwere manier van async code

  • Ziet eruit als “gewone” code

  • await werkt alleen in een async functie

Async / Await

async function loadData() {
  const url = "https://www.pgm.gent/data/emojis/emojis.json";
  const response = await fetch(url);
  const data = await response.json();
  console.log(data);
}
loadData();
  • Hou ook rekening met errors via try/catch

Catch?

async function loadData() {
  try {
    const url = "https://www.pgm.gent/data/emojis/emojis.json";
  	const response = await fetch(url);
  	const data = await response.json();
  	console.log(data);
  } catch (err) {
    console.error("Fout:", err);
  }
}
loadData();

Optie 1: then                           Optie 2: async/await

Vergelijking

async function loadData() {
  try {
  	const response = await fetch(url);
  	const data = await response.json();
  	console.log(data);
  } catch (err) {
    console.error("Fout:", err);
  }
}
loadData();
fetch(url)
  .then(res => res.json())
  .then(data => {
        console.log(data);
   })
  .catch(err => console.error("Fout:", err));

Error handling

Fetch

  • fetch maakt enkel een error aan bij netwerk problemen (bv. server down, wifi niet werkend, ...)

  • Andere problemen (500, 404, ...) komen niet in catch terecht. Deze moet je zelf opvangen.

Probleem

Zelf opvangen

fetch("https://api.example.com/data")
  .then(response => {
    if (!response.ok) {        
      // response.ok is false bij 4xx of 5xx
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => console.log("DATA:", data))
  .catch(err => console.error("ERROR:", err));

Door een Error te "throwen" binnen de promise, zal JS naar catch gaan en niet langer naar then!