Utmaningar
Nedan finns nio frågor om JSON, promises, fetch() och CORS. Frågorna bygger på veckans artiklar
HTTP och JSON, Promises och async/await och
Nätverksanrop med fetch.
Varje fråga har ett antal alternativ att välja bland. Klicka på “Visa lösning” för att se svaret och förklaringen.
Om du är osäker kan du alltid testa i webbläsarens devtools-konsol eller ta upp frågan på en handledning.
Fråga 12-01: Vad är fel i JSON-texten?
Section titled “Fråga 12-01: Vad är fel i JSON-texten?”{ "title": 'Röda rummet', "year": 1879,}- Inget, texten är giltig JSON.
- Strängen har enkla citattecken.
- Det finns ett kommatecken efter sista egenskapen.
- Både 2 och 3.
Lösningsförslag
Section titled “Lösningsförslag”Svaret är alternativ 4. I JSON skrivs alla strängar och nycklar med dubbla citattecken, och det får
inte finnas något kommatecken efter sista elementet. Båda är tillåtna i ett objekt i JavaScript,
vilket gör felen lätta att missa. JSON.parse() kastar ett SyntaxError för texten.
Fråga 12-02: Vad blir resultatet?
Section titled “Fråga 12-02: Vad blir resultatet?”JSON.stringify({ a: 1, b: undefined, c: () => 2 })'{"a":1,"b":undefined,"c":"() => 2"}''{"a":1}''{"a":1,"b":null,"c":null}'- Ett
TypeErrorkastas.
Lösningsförslag
Section titled “Lösningsförslag”Svaret är alternativ 2, '{"a":1}'. JSON saknar undefined och funktioner, så
JSON.stringify() hoppar över egenskaper med sådana värden utan att kasta något fel. I en array
blir de i stället null, eftersom positionerna måste finnas kvar: JSON.stringify([1, undefined])
ger '[1,null]'.
Fråga 12-03: I vilken ordning skrivs siffrorna ut?
Section titled “Fråga 12-03: I vilken ordning skrivs siffrorna ut?”console.log('1')
setTimeout(() => console.log('2'), 0)
Promise.resolve().then(() => console.log('3'))
async function run() { console.log('4') await null console.log('5')}
run()
console.log('6')1,2,3,4,5,61,4,6,3,5,21,4,6,2,3,51,6,4,3,5,2
Lösningsförslag
Section titled “Lösningsförslag”Svaret är alternativ 2.
Skriptet körs först klart: 1, sedan 4, eftersom en async-funktion körs synkront fram till sitt
första await, och sist 6. Under tiden har två microtasks hamnat i kön: funktionen i then()
och resten av run() efter await. De körs i den ordningen, 3 och 5, så snart skriptet är
klart. Timern är en task och får vänta tills alla microtasks är körda, så 2 kommer sist.
Fråga 12-04: Vad innehåller result?
Section titled “Fråga 12-04: Vad innehåller result?”async function getBook(id) { const response = await fetch(`https://api.example.com/books/${id}`) return response.json()}
const result = getBook(42)- Boken, som ett objekt.
undefined, eftersom svaret inte har kommit än.- Ett promise som är pending.
- Ett
Response-objekt.
Lösningsförslag
Section titled “Lösningsförslag”Svaret är alternativ 3. En async-funktion returnerar alltid ett promise, direkt när den anropas.
Promiset blir fulfilled med boken först när svaret har kommit och tolkats. För att komma åt boken
behövs await getBook(42) eller getBook(42).then(...).
Fråga 12-05: Vad händer när servern svarar 500?
Section titled “Fråga 12-05: Vad händer när servern svarar 500?”try { const response = await fetch('https://api.example.com/books') console.log(response.status)} catch { console.log('Error')}Errorskrivs ut, eftersomfetch()kastar ett fel.500skrivs ut.- Ett
TypeErrorkastas, men fångas inte. - Ingenting skrivs ut.
Lösningsförslag
Section titled “Lösningsförslag”Svaret är alternativ 2, 500. Ett svar med en felkod är fortfarande ett svar, så promiset från
fetch() blir fulfilled och catch körs inte. Promiset blir rejected bara när inget svar kan
läsas: vid nätverksfel, när CORS stoppar förfrågan eller när den avbryts. Därför måste du själv
kontrollera response.ok och kasta ett fel.
Fråga 12-06: Hur lång tid tar det?
Section titled “Fråga 12-06: Hur lång tid tar det?”function wait(milliseconds) { return new Promise((resolve) => setTimeout(resolve, milliseconds))}
await Promise.all([wait(1000), wait(2000), wait(500)])Ungefär hur lång tid tar det innan raden med Promise.all() är klar?
- 0,5 sekunder
- 1 sekund
- 2 sekunder
- 3,5 sekunder
Lösningsförslag
Section titled “Lösningsförslag”Svaret är alternativ 3, 2 sekunder. Alla tre timrarna startar direkt när wait() anropas och
räknar samtidigt. Promise.all() blir fulfilled när den sista är klar, alltså efter den längsta
tiden. Hade de tre väntat med await en i taget hade det tagit 3,5 sekunder. Med
Promise.race() eller Promise.any() hade det tagit 0,5 sekunder.
Fråga 12-07: Vad blir resultatet?
Section titled “Fråga 12-07: Vad blir resultatet?”const result = await Promise.all([ Promise.resolve(1), Promise.reject(new Error('Failed')), Promise.resolve(3)])[1, undefined, 3][1, Error, 3][1, 3]- Inget resultat. Raden kastar felet
Failed.
Lösningsförslag
Section titled “Lösningsförslag”Svaret är alternativ 4. Promise.all() blir rejected så fort ett av promisen misslyckas, med just
det felet, och await kastar det. Vill du ha resultatet av alla använder du
Promise.allSettled(), som ger en array med { status: 'fulfilled', value } eller
{ status: 'rejected', reason } för vart och ett.
Fråga 12-08: Vilken URL har samma origin?
Section titled “Fråga 12-08: Vilken URL har samma origin?”Sidan körs på https://app.example.com. Vilken av URL:erna har samma origin?
https://app.example.com:443/api/bookshttp://app.example.com/api/bookshttps://api.example.com/bookshttps://example.com/api/books
Lösningsförslag
Section titled “Lösningsförslag”Svaret är alternativ 1. En origin består av protokoll, värdnamn och port. https har port 443
som standard, så https://app.example.com och https://app.example.com:443 är samma origin, trots
att de är skrivna olika. Alternativ 2 har ett annat protokoll, och alternativ 3 och 4 har andra
värdnamn. Att de delar domänen example.com spelar ingen roll.
Fråga 12-09: Vilken förfrågan föregås av en preflight-förfrågan?
Section titled “Fråga 12-09: Vilken förfrågan föregås av en preflight-förfrågan?”Alla förfrågningar görs med fetch() till en annan origin än sidans egen.
- En
GETutan egna headrar. - En
POSTmedContent-Type: application/x-www-form-urlencoded. - En
POSTmedContent-Type: application/json. - Inget av dem; webbläsaren skickar alltid en preflight-förfrågan.
Lösningsförslag
Section titled “Lösningsförslag”Svaret är alternativ 3. En GET utan egna headrar och en POST med en body av den sort ett
HTML-formulär kan skicka är simple requests, och skickas direkt. application/json kan ett
formulär inte skicka, så webbläsaren frågar först servern med en OPTIONS-förfrågan om förfrågan är
tillåten. Det är därför en POST med JSON till B2:s API syns som två rader i fliken Network.