introduktion till löften
ett löfte definieras vanligen som en proxy för ett värde som så småningom kommer att bli tillgängligt.
löften är ett sätt att hantera asynkron kod, utan att fastna i callback hell.
löften har varit en del av språket i flera år (standardiserad och introducerad i ES2015), och har nyligen blivit mer integrerade, med async och väntar i ES2017.,
async-funktioner använder löften bakom kulisserna, så att förstå hur löften fungerar är grundläggande för att förstå hur async
och await
fungerar.
hur löften fungerar, i korthet
När ett löfte har ringts, startar det i ett väntande tillstånd. Det innebär att uppringningsfunktionen fortsätter att utföra, medan löftet väntar tills det löser sig, vilket ger uppringningsfunktionen vilken data som begärdes.,
det skapade löftet kommer så småningom att sluta i ett löst tillstånd, eller i ett avvisat tillstånd, och anropa respektive återuppringningsfunktioner (skickas till then
och catch
) efter avslutad behandling.
vilka JS API: er använder löften?
förutom din egen kod och bibliotek kod, löften används av standard moderna webb API: er som:
- batteriet API
- hämta API
- servicearbetare
det är osannolikt att du i modern JavaScript inte hittar dig själv med löften, så låt oss börja dyka rätt in i dem.,
skapa ett löfte
Promise API exponerar en promise constructor, som du initierar mednew Promise()
:
som du kan se kontrollerar löftetdone
global constant, och om det är sant går löftet till ett löst tillstånd (eftersomresolve
återuppringning kallades); annars körsreject
återuppringning, vilket ger löftet i ett avvisat tillstånd., (Om ingen av dessa funktioner anropas i körningssökvägen kommer löftet att förbli i väntande tillstånd)
medresolve
ochreject
kan vi kommunicera tillbaka till den som ringer vad det resulterande löftets tillstånd var och vad vi ska göra med det. I ovanstående fall returnerade vi bara en sträng, men det kan vara ett objekt, eller null
också. Eftersom vi har skapat löftet i ovanstående utdrag har det redan börjat exekvera. Detta är viktigt att förstå vad som händer i avsnittet konsumerar ett löfte nedan.,
ett vanligare exempel som du kan stöta på är en teknik som kallas Promisifying. Denna teknik är ett sätt att kunna använda en klassisk JavaScript-funktion som tar en återuppringning, och få det tillbaka ett löfte:
i de senaste versionerna av Node.js, du behöver inte göra den här manuella konverteringen för mycket av API: n. Det finns en promisifying funktion tillgänglig i util-modulen som kommer att göra detta för dig, med tanke på att funktionen du promisifying har rätt signatur.,
konsumerar ett löfte
i det sista avsnittet introducerade vi hur ett löfte skapas.
låt oss nu se hur löftet kan konsumeras eller användas.
körcheckIfItsDone()
kommer att ange funktioner som ska köras närisItDoneYet
löfte löser (ithen
samtal) eller avvisar (icatch
samtal).
kedja löften
ett löfte kan returneras till ett annat löfte och skapa en kedja av löften.,
ett bra exempel på kedja löften är Hämta API, som vi kan använda för att få en resurs och köa en kedja av löften att utföra när resursen hämtas.
hämta API är en löftesbaserad mekanism, och anropa fetch()
motsvarar att definiera vårt eget löfte med new Promise()
.
exempel på kedja löften
i det här exemplet kallar vifetch()
för att få en lista över todo-objekt från filentodos.json
som finns i domänroten, och vi skapar en kedja av löften.,
Runningfetch()
returnerar ett svar, som har många egenskaper, och inom de som vi refererar till:
-
status
, ett numeriskt värde som representerar HTTP-statuskoden -
statusText
, ett statusmeddelande, som ärOK
om begäran lyckades
response
har också enjson()
metod, som returnerar ett löfte som kommer att lösa med innehållet i kroppen bearbetas och omvandlas till JSON.,
så med tanke på dessa lokaler är detta vad som händer: det första löftet i kedjan är en funktion som vi definierade, kallad status()
, som kontrollerar svarsstatus och om det inte är ett framgångsrespons (mellan 200 och 299), avvisar det löftet.
den här åtgärden kommer att leda till att promise-kedjan hoppar över alla kedjade löften som listas och kommer att hoppa direkt tillcatch()
– satsen längst ner och loggaRequest failed
– texten tillsammans med felmeddelandet.,
om det lyckas i stället anropar det funktionen json()
som vi definierade. Sedan det tidigare löftet, när det lyckades, återvänderesponse
– objektet, får vi det som en inmatning till det andra löftet.
i det här fallet returnerar vi data JSON som behandlas, så det tredje löftet tar emot JSON direkt:
.then((data) => { console.log('Request succeeded with JSON response', data)})
och vi loggar det helt enkelt till konsolen.
hantering av fel
i exemplet, i föregående avsnitt, hade vi en catch
som bifogades till kedjan av löften.,
När något i kedjan av löften misslyckas och väcker ett fel eller avvisar löftet, går kontrollen till närmastecatch()
uttalande ner kedjan.
Cascading fel
om inuticatch()
du höjer ett fel, kan du lägga till en sekundcatch()
för att hantera det, och så vidare.
new Promise((resolve, reject) => { throw new Error('Error')}) .catch(err => { throw new Error('Error') }) .catch(err => { console.error(err) })
orkestrerande löften
löfte.,all ()
om du behöver synkronisera olika löften hjälper Promise.all()
dig att definiera en lista med löften och utföra något när de är alla lösta.
exempel:
ES2015 destructuring assignment syntax kan du också göra
Promise.all().then(() => { console.log('Results', res1, res2)})
du är inte begränsad till att användafetch
naturligtvis kan alla löften användas på detta sätt.
löfte.,race ()
Promise.race()
körs när den första av de löften du passerar till det löser, och det körs den bifogade återuppringning bara en gång, med resultatet av det första löftet löst.,
exempel:
vanliga fel
Uncaught TypeError: undefined är inte ett löfte
om du får feletUncaught TypeError: undefined is not a promise
I konsolen, se till att du användernew Promise()
istället för baraPromise()
unhandledpromiserejectionwarning
detta innebär att ett löfte du kallade avvisas, men det fanns ingencatch
används för att hantera felet. Lägg till encatch
efter den kränkandethen
för att hantera detta korrekt.