Introduktion till promises i JavaScript
Du vet redan att användning av callback-modellen för asynkronitet lätt leder till en situation som kallas callback hell. Därför introducerades en ny modell i JavaScript som kallas promises (promise). Låt oss studera denna modell.
Ett promise är ett objekt, där en funktion skickas in som en parameter, och inuti denna funktion ska vi placera vår asynkrona kod:
let promise = new Promise(function() {
// asynkron kod
});
Som du ser, sparade jag objektet med promiset
i variabeln promise. På någon annan plats i koden
kan jag applicera metoden then på denna variabel,
och skicka med en funktion
med koden som ska köras när
den asynkrona koden, skriven
när detta promise skapades, är slutförd:
promise.then(function() {
// körs när den asynkrona koden är klar
});
Det låter förvirrande, så låt oss titta på ett exempel. Låt oss säga att jag har följande asynkrona kod:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Låt oss säga att jag vill lösa vårt huvudsakliga
asynkronitetsproblem för detta: köra viss
kod efter att timern har utlösts. Samtidigt
vill jag inte placera denna kod i själva timern
och vill att resultatet,
som jag skrev i variabeln result, på något sätt ska komma med i denna kod.
I princip har vi löst detta problem i tidigare
lektioner genom callbacks och prenumerationer. Låt oss
nu se hur man gör detta med promises.
Först måste vi slå in vår asynkrona kod i ett promise:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Detta är dock inte tillräckligt. Vi måste explicit ange att vår asynkrona kod är slutförd. Hjälp oss med detta genom en speciell avslutsfunktion, som automatiskt hamnar i den första parametern av funktionen om den anges:
let promise = new Promise(function(resolve) { // anger parameter
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Med hjälp av avslutsfunktionen kan vi explicit indikera för promiset att den asynkrona koden är slutförd. För att göra detta måste vi anropa denna funktion på den plats där vi vill:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // avslutar promiset
}, 3000);
});
Om vi vill skicka något form av resultat från den asynkrona koden utåt, kan vi skicka det som en parameter till vår avslutsfunktion:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // skickar resultatet
}, 3000);
});
Man kan naturligtvis bli av med den mellanliggande variabeln:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Nu kan vi på vilken annan plats som helst anropa
metoden then på vårt promise:
promise.then(function() {
// triggas när promiset är klart
});
Resultatet från promiset hamnar i den första parametern av funktionen om vi väljer att ange den:
promise.then(function(result) {
console.log(result); // skriver ut arrayen med resultatet
});
Skapa ett promise, inuti vilket det ska finnas en fördröjning
på 5 sekunder, varefter promiset ska
slutföras och returnera någon text som sitt resultat.
Skriv ut denna text på skärmen.