Komma igång med JavaScript-löften
Asynkron kod är användbart för att utföra uppgifter som är tidskrävande men det är det självklart inte saknar nackdelar. Asynkod använder återuppringningsfunktioner att bearbeta sina resultat, men återuppringningsfunktioner kan inte returnera värden som typiska JavaScript-funktioner kan.
Således tar de inte bara vår förmåga att kontrollera utförande av funktionen men också göra felhantering lite besvär. Det är här Löfte
objekt kommer in, eftersom det syftar till att fylla i några av potholes i asynkron kodning.
Löfte
är tekniskt a standard internt objekt i JavaScript, vilket betyder att den kommer inbyggd i JavaScript. Det används för att representera eventuellt resultat av ett asynkront kodblock (eller anledningen till att koden misslyckades) och har metoder för att styra utförande av den asynkrona koden.
Syntax
Vi kan skapa en förekomst av Löfte
objekt använda ny
nyckelord:
nytt löfte (funktion (lösa, avvisa) );
Funktionen passerat som en parameter till Löfte()
konstruktorn är känd som testamentsexekutor. Den innehåller asynkron kod och har två parametrar av Fungera
typ, kallad lösa
och avvisa
funktioner (mer om dessa inom kort).
Staterna i Löfte
objekt
De initialtillstånd av a Löfte
objekt heter avvaktan. I detta tillstånd, resultatet av den asynkrona beräkningen existerar inte.
Den ursprungliga väntande staten ändras till uppfyllda Ange när beräkningen är framgångsrik. De Resultatet av beräkningen finns i detta tillstånd.
Vid asynkron beräkning misslyckas, de Löfte
objekt flyttas till avvisade Ange från början avvaktan stat. I detta tillstånd orsaken till beräkningsfelet (dvs felmeddelande) görs tillgängligt.
Att gå från avvaktan till uppfyllda stat, lösa()
kallas. Att gå från avvaktan till avvisade stat, avvisa()
kallas.
De sedan
och fånga
metoder
När staten ändras från avvaktan till uppfyllda, händelsehanteraren av Löfte
objekt sedan
metod exekveras. Och när staten ändras från avvaktan till avvisade, händelsehanteraren av Löfte
objekt fånga
metod exekveras.
Exempel 1
“Icke-Promisified” koda
Antag att det finns en hello.txt
fil som innehåller “Hej” ord. Så här kan vi skriva en AJAX-begäran till hämta den filen och visa innehållet, utan att använda Löfte
objekt:
funktion getTxt () let xhr = new XMLHttpRequest (); xhr.open ('GET', 'hej.txt'); xhr.overrideMimeType ( 'text / plain'); xhr.send (); xhr.onload = function () försök switch (this.status) case 200: document.write (this.response); ha sönder; fall 404: kasta "filen hittades inte"; standard: kasta 'Misslyckades med att hämta filen'; fånga (err) console.log (err); getTxt ();
Om innehållet i filen har varit hämtas framgångsrikt, d.v.s.. svarstatuskoden är 200, svartexten är skrivet i dokumentet. Om filen är inte hittat (status 404), en “Filen hittades inte” Felmeddelandet kastas. Annars a generellt felmeddelande Indikerar misslyckandet att hämta filen kastas.
“Promisified” koda
Nu, låt oss Promisifiera ovanstående kod:
funktion getTxt () returnera nytt Promise (funktion (lösa, avvisa) let xhr = new XMLHttpRequest (); xhr.open ('GET', 'hello.txt'); xhr.overrideMimeType ('text / plain'); xhr.send (); xhr.onload = function () switch (this.status) fall 200: lösa (this.response); fall 404: reject ("File not Found"); default: reject hämta filen ');;); getTxt (). sedan (funktion (txt) document.write (txt);). fånga (funktion (err) console.log (err););
De getTxt ()
funktionen är nu kodad till returnera en ny instans av Löfte
objekt, och dess exekveringsfunktion håller den asynkrona koden från tidigare.
När Svarstatuskoden är 200, de Löfte
är uppfyllda av kallelse lösa()
(svaret överförs som parameter för lösa()
). När statuskoden är 404 eller någon annan, Löfte
är avvisade använder sig av avvisa()
(med lämpligt felmeddelande som parameter för avvisa()
).
De händelsehanterare för sedan()
och fånga()
metoder av Löfte
objekt är lagt till i slutet.
När Löfte
är uppfyllda, handlaren av sedan()
Metoden körs. Dess argument är parametern passerade från lösa()
. Inne i händelsehanteraren är svartexten (mottagen som argumentet) skrivet i dokumentet.
När Löfte
är avvisade, händelsehanteraren av fånga()
Metoden körs, loggar felet.
De största fördelen av ovanstående Promisified version av koden är felhantering. Istället för att kasta oskydda undantag runt - som i den icke-promissiverade versionen - lämpliga felmeddelanden returneras och loggas.
Men det är inte bara återvändande av felmeddelanden men också av Resultatet av den asynkrona beräkningen Det kan vara verkligt fördelaktigt för oss. För att se det måste vi utöka vårt exempel.
Exempel 2
“Icke-Promisified” koda
Istället för att bara visa texten från hello.txt
, jag vill kombinera den med “Värld” ord och visa den på skärmen efter en time-out av 2 sekunder. Här är koden jag använder:
funktion getTxt () let xhr = new XMLHttpRequest (); xhr.open ('GET', 'hej.txt'); xhr.overrideMimeType ( 'text / plain'); xhr.send (); xhr.onload = function () försök switch (this.status) case 200: document.write (concatTxt (this.response)); ha sönder; fall 404: kasta "filen hittades inte"; standard: kasta 'Misslyckades med att hämta filen'; fånga (err) console.log (err); funktion concatTxt (res) setTimeout (funktion () return (res + 'World'), 2000); getTxt ();
På statuskoden 200, är concatTxt ()
funktion kallas till sammanfatta svartexten med “Värld” ord innan du skriver in det i dokumentet.
Men den här koden kommer inte att fungera som önskat. De setTimeout ()
återuppringningsfunktion kan inte returnera den sammanlänkade strängen. Det som kommer att skrivas ut till dokumentet är odefinierad
för det är det Vad concatTxt ()
avkastning.
“Promisified” koda
Så, för att få koden att fungera, låt oss Promisifiera ovanstående kod, Inklusive concatTxt ()
:
funktion getTxt () returnera nytt Promise (funktion (lösa, avvisa) let xhr = new XMLHttpRequest (); xhr.open ('GET', 'hello.txt'); xhr.overrideMimeType ('text / plain'); xhr.send (); xhr.onload = function () switch (this.status) fall 200: lösa (this.response); fall 404: reject ("File not Found"); default: reject hämta filen ');;); funktion concatTxt (txt) return new Promise (funktion (lösa, avvisa) setTimeout (function () resolve (txt + 'World');, 2000);); getTxt () sedan ((txt) => return concatTxt (txt);). då ((txt) => document.write (txt);). fånga ((err) => konsol. logga (err););
Precis som getTxt ()
, de concatTxt ()
funktion också returnerar en ny Löfte
objekt istället för den sammanlänkta texten. De Löfte
returneras av concatTxt ()
är löst inom återuppringningsfunktionen av setTimeout ()
.
Nära slutet av ovanstående kod, händelsehanteraren av den första sedan()
Metoden körs när Löfte
av getTxt ()
är uppfyllda, dvs när filen är hämtas framgångsrikt. Inuti den hanteraren, concatTxt ()
kallas och den Löfte
returneras av concatTxt ()
returneras.
Evenemangshanteraren på den andra sedan()
Metoden körs när Löfte
returneras av concatTxt ()
är uppfyllda, d.v.s. två sekunder time-out är över och lösa()
kallas med den sammanlänkade strängen som dess parameter.
Till sist, fånga()
fångar alla undantag och felmeddelanden från båda löften.
I denna Promisified version, the “Hej världen” strängen kommer att vara skrivs ut med framgång till dokumentet.