FJS26 · V47 · ONSDAG

async, await
och felhantering

Samma promises, och allt som kan gå fel.

Chas Academy · Onsdag 18 november 2026


Idag

01async och await02Felhantering03Flera anrop04Avbryta05Data som saknar fält06Efter passet
ASYNC, AWAIT OCH FELHANTERING2 / 25
”

Igår: en promise är ett värde som kommer senare. Idag: hur vi väntar på det, och vad vi gör när det inte kommer.

01

async och
await

ASYNC OCH AWAIT


Samma sak, två sätt

Med then

fetch(url)
  .then((response) => response.json())
  .then((user) => console.log(user.name))
  .catch((error) => console.error(error));

Med async och await

const getUser = async () => {
  try {
    const response = await fetch(url);
    const user = await response.json();
    console.log(user.name);
  } catch (error) {
    console.error(error);
  }
};
ASYNC, AWAIT OCH FELHANTERING5 / 25

ASYNC OCH AWAIT


Två regler

async returnerar alltid en promise

const getNumber = async () => 42;

getNumber();  // Promise { 42 }
await getNumber();  // 42

await pausar bara funktionen

const demo = async () => {
  console.log('A');
  await wait(0);
  console.log('B');
};
demo();
console.log('C');
// A, C, B
ASYNC, AWAIT OCH FELHANTERING6 / 25
02

Felhantering

Det som skiljer en app som fungerar från en som ser trasig ut.

FELHANTERING


fetch kastar inte fel vid 404

Koden

const response = await fetch(
  '.../users/999',
);
response.status;  // 404
response.ok;      // false
await response.json();  // {}

Varför?

404 och 500 är svar från servern. Nätverket fungerade, så för fetch gick det bra. fetch kastar bara fel när det inte kommer något svar alls: ingen uppkoppling, fel domän, CORS.

ASYNC, AWAIT OCH FELHANTERING8 / 25

FELHANTERING


En egen fetchJson

Kolla response.ok på ett ställe, i stället för i varje anrop.

fetchJson

const fetchJson = async (url, options) => {
  const response = await fetch(url, options);
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }
  return await response.json();
};

Användningen

try {
  const user = await fetchJson(url);
  show(user);
} catch (error) {
  showError(error.message);
}
ASYNC, AWAIT OCH FELHANTERING9 / 25

FELHANTERING


Tre lägen med finally

Koden

const showUser = async (id) => {
  status.textContent = 'Laddar...';
  button.disabled = true;
  try {
    const user = await fetchJson(urlFor(id));
    status.textContent = user.name;
  } catch (error) {
    status.textContent = 'Kunde inte hämta. Försök igen.';
  } finally {
    button.disabled = false;
  }
};

Laddar, fel, lyckat

try: det som ska hända när allt går bra. catch: ett fel som användaren förstår, inte bara console.log. finally: det som ska hända oavsett, som att sätta på knappen igen.

ASYNC, AWAIT OCH FELHANTERING10 / 25
”

Fånga felet där du vet vad som ska hända. Hjälpfunktionen vet inte det, så den kastar vidare. Den som visar sidan bestämmer.

03

Flera anrop

FLERA ANROP


Ett i taget eller alla samtidigt

Ett i tagetawait, await, awaitusers/1users/2users/3tiderna läggs ihopAlla samtidigtawait Promise.all([...])users/1users/2users/3lika länge som det långsammastetid
ASYNC, AWAIT OCH FELHANTERING13 / 25

FLERA ANROP


Promise.all

Ett i taget

const a = await fetchJson(userUrl(1));
const b = await fetchJson(userUrl(2));
const c = await fetchJson(userUrl(3));

Alla samtidigt

const [a, b, c] = await Promise.all([
  fetchJson(userUrl(1)),
  fetchJson(userUrl(2)),
  fetchJson(userUrl(3)),
]);
ASYNC, AWAIT OCH FELHANTERING14 / 25

FLERA ANROP


När ett av dem misslyckas

Promise.all

Ger upp vid första felet. De som lyckades får du aldrig se. Bra när du behöver alla för att kunna visa något.

Promise.allSettled

Väntar på alla och berättar hur det gick för var och en.

const results = await Promise.allSettled([...]);

results.map((r) =>
  r.status === 'fulfilled'
    ? r.value.name
    : r.reason.message,
);
ASYNC, AWAIT OCH FELHANTERING15 / 25

FLERA ANROP


Promise.race

Den första vinner

const timeout = (ms) =>
  wait(ms).then(() => {
    throw new Error('För långsamt');
  });

await Promise.race([
  fetchJson(slowUrl),
  timeout(2000),
]);

Men

race slutar vänta, men anropet fortsätter i bakgrunden. Vill du verkligen avbryta det behövs en AbortController.

ASYNC, AWAIT OCH FELHANTERING16 / 25
04

Avbryta

AVBRYTA


AbortController

Koden

let controller = null;

start.addEventListener('click', async () => {
  controller?.abort();
  controller = new AbortController();
  try {
    await fetch(url, { signal: controller.signal });
  } catch (error) {
    if (error.name === 'AbortError') return;
    showError(error);
  }
});

cancel.addEventListener('click', () => controller?.abort());

När behövs det?

En sökning där användaren skriver vidare: avbryt den förra innan nästa startar, annars kan ett gammalt svar komma sist och skriva över det nya. Ett avbrutet anrop är inget fel. Visa det inte som ett.

ASYNC, AWAIT OCH FELHANTERING18 / 25

AVBRYTA


Timeout utan egen kod

AbortSignal.timeout

try {
  await fetch(url, {
    signal: AbortSignal.timeout(5000),
  });
} catch (error) {
  error.name;  // 'TimeoutError'
}

Tre sorters fel

TypeError: inget svar alls, till exempel utan nät. AbortError: någon avbröt. TimeoutError: tiden tog slut. Och ditt eget Error när response.ok är false.

ASYNC, AWAIT OCH FELHANTERING19 / 25

Övning

Avbryt och timeout

Gör del 4: koppla en AbortController till knapparna Starta och Avbryt, visa Avbrutet i stället för ett fel, och prova AbortSignal.timeout(2000) mot https://httpbin.org/delay/5.

Tid

10 min

Mål

Du kan avbryta ett anrop och skilja ett avbrott från ett fel.

ASYNC, AWAIT OCH FELHANTERING20 / 25
05

Data som
saknar fält

Data från ett API har inte alltid alla fält.

DATA SOM SAKNAR FÄLT


?. när något kanske saknas

Utan

user.address.city
// TypeError: Cannot read properties
// of undefined (reading 'city')

Med optional chaining

user.address?.city
// undefined

controller?.abort()
// anropas bara om controller finns
ASYNC, AWAIT OCH FELHANTERING22 / 25

DATA SOM SAKNAR FÄLT


?? mot ||

Båda ger ett reservvärde. Frågan är vad som räknas som saknat.

|| byter ut allt falsy

'', 0, false, null och undefined.

const orders = 0;
orders || 'okänt';  // 'okänt'

?? byter bara ut null och undefined

Noll beställningar är fortfarande ett svar.

const orders = 0;
orders ?? 'okänt';  // 0
ASYNC, AWAIT OCH FELHANTERING23 / 25
06

Efter passet

EFTER PASSET


Inför workshoppen

  • Gör klart del 4 och 5 i code-alongen om du inte hann.
  • I morgon, på plats: en väderapp mot Open-Meteo med fetchJson, de tre lägena, Promise.allSettled, AbortController och ??.
  • Läs: Async/await på javascript.info och Using the Fetch API på MDN, om du vill ha det i text.
ASYNC, AWAIT OCH FELHANTERING25 / 25