JavaScript, gjennom sin popularitet og de siste forbedringene, blir i økende grad webprogrammererens beste venn. Og som alle beste venner, holder JavaScript sine løfter.
Nå kan det høres litt rart, men det er sant. De fleste nettlesere støtter det som kalles Promise-objektet. Et løfte er ganske som en funksjon ved at den representerer et stykke kode eller en oppgave som du vil bli henrettet på et tidspunkt i fremtiden.
Her ser det ut som et løfte.
var myPromise = nytt løfte (funksjon (løse, avvise) // Oppgave å utføre går her.);
Du kan se her at når vi lager et løfte, gir vi det et enkelt argument, som er en funksjon som inneholder kode som vi ønsker å utføre på et tidspunkt i fremtiden. Du har kanskje også lagt merke til de to argumentene i funksjonen som ble overført til løftet, Løse
og avvise
. Disse er også funksjoner og er vår måte å fortelle løftet om det har gjort det det lovte å gjøre. Slik bruker du dem:
var myPromise = nytt løfte (funksjon (løse, avvise) if (true) resolve ('Hello Tuts + fans!'); else reject ('Aww, fungerte ikke' '););
Dette løftet er åpenbart alltid å løse som hvis
uttalelse vil alltid være sant. Dette er bare for læringsformål - vi vil gjøre noe mer realistisk senere - men forestill deg å erstatte ekte
med et kodestykke som du ikke var 100% sikker på, skulle jobbe.
Nå som vi har laget et løfte, hvordan bruker vi det? Vel, vi må fortelle det hva de Løse
og avvise
funksjoner er. Vi gjør dette ved å bruke løftet deretter
metode.
myPromise.then (funksjon (resultat) // Oppløs tilbakeringing. console.log (result);, funksjon (resultat) // Avvis tilbakering. console.error (result););
Fordi vår hvis erklæring alltid passerer sin ekte
sjekk, koden ovenfor vil alltid logge "Hei Tuts + fans!" til konsollen. Det vil også gjøre det umiddelbart. Dette skyldes at koden i Promises konstruktør er synkron, noe som betyr at den ikke venter på noen operasjon som skal utføres. Den har all den informasjonen den trenger for å fortsette og gjør det så snart som mulig.
Hvor løfter virkelig skinner, er imidlertid når det gjelder asynkrone oppgaver - oppgaver der du ikke vet når akkurat det løftet blir oppfylt. Et ekte eksempel på en asynkron oppgave er å hente en ressurs, for eksempel en JSON-fil, for eksempel via AJAX. Vi vet ikke hvor lenge serveren skal ta for å svare, og det kan til og med mislykkes. La oss legge til noen AJAX i vår løftekode.
var myPromise = nytt løfte (funksjon (løse, avvise) // Standard AJAX forespørselsoppsett og last. var request = new XMLHttpRequest (); // Be om en brukers kommentar fra vår falske blogg. request.open ('GET' http://jsonplaceholder.typicode.com/posts/1 '); // Sett funksjon for å ringe når ressursen er lastet. request.onload = function () if (request.status === 200) løse (forespørsel. svar); else reject ('Side lastet, men status ikke OK.');; // Angi funksjon for å ringe når lasting mislykkes. request.onerror = function () reject ('Aww, did not jobbe i det hele tatt. '); request.send (););
Koden her er bare standard JavaScript for å utføre en AJAX-forespørsel. Vi ber om en ressurs, i dette tilfellet en JSON-fil på en spesifisert nettadresse, og venter på at den skal svare. Vi vet aldri nøyaktig når. Og vi vil selvsagt ikke stoppe utførelsen av utskrift for å vente på det, så hva gjør vi?
Vel, heldigvis har vi satt denne koden i et løfte. Ved å sette det her, sier vi i utgangspunktet: "Hei stykke kode, jeg må gå akkurat nå, men jeg vil ringe deg senere og fortelle deg når du skal kjøre. Lov om at du skal gjøre det og fortelle meg når du er ferdig? " Og koden vil si, "Ja, selvfølgelig. Jeg lover."
En viktig ting å merke seg i koden ovenfor er kallelsen til Løse
og avvise
funksjoner. Husk at dette er vår måte å fortelle vårt løfte om at vår kode har eller ikke har utført. Ellers vet vi aldri.
Ved å bruke den samme koden fra vårt grunnleggende eksempel, kan vi se hvordan vår AJAX-forespørsel inne i løftet vil fungere nå.
// Fortell vårt løfte om å utføre sin kode // og fortell oss når det er gjort. myPromise.then (funksjon (resultat) // Skriver mottatt JSON til konsollen. console.log (result);, funksjon (resultat) // Utskrifter "Aww fungerte ikke" eller // "Side lastet, men status ikke OK. "console.error (result););
Jeg visste at vi kunne stole på deg, myPromise
.
Nå kan du tenke på dette punktet at løfter bare er fancy tilbakeringingsfunksjoner med en bedre syntaks. Det er sant i en grad, men for å fortsette med vårt AJAX-eksempel, si at du trengte å gjøre noen flere forespørsler, hver forespørsel basert på resultatet av det siste. Eller hva om du trengte å behandle JSON først?
Å gjøre dette med tilbakekalling vil ende i tunge nesting av funksjoner, hver blir stadig vanskeligere å holde styr på. Heldigvis, i løfteverdenen kan vi sammenkoble slike funksjoner sammen slik. Her er et eksempel der når vi mottar JSON for en brukers kommentar til vår falske blogg, så vil vi sørge for at det er helt små bokstaver før vi gjør noe annet med det.
myPromise .then (funksjon (resultat) // Når vi mottar JSON, // slå det inn i et JSON objekt og returner. Return JSON.parse (result);) .then (funksjon (parsedJSON) // Når json har har blitt analysert, // få e-postadressen og få den små bokstaver. returnere parsedJSON.email.toLowerCase ();) .then (funksjon (emailAddress) // Når teksten er gjort små bokstaver, // skriv den ut til konsollen. console.log (emailAddress);, funksjon (err) // Noe i ovennevnte kjede gikk galt? // Print reject output. console.error (err););
Du kan se her at mens vår opprinnelige samtale var asynkron, er det også mulig å sette sammen synkronte samtaler. Koden i hver Løse
fungere inne i deretter
vil bli kalt når hver av dem returnerer. Du vil også legge merke til at det bare er én feilfunksjon angitt her for hele kjeden. Ved å plassere dette på enden av kjeden som avvise
funksjon i det siste deretter
, ethvert løfte i kjeden som ringer avvise
vil ringe denne.
Nå som vi er litt mer selvsikker med løfter, la oss lage en annen sammen med den ovenfor. Vi lager en som tar vår nye små e-postadresse, og vil (late som) sende en e-post til den adressen. Dette er bare et eksempel for å illustrere noe asynkront. Det kan være noe, som å kontakte en server for å se om e-posten var på en hvitliste eller om brukeren er logget inn. Vi må gi e-postadressen til det nye løftet, men løfter godtar ikke argumenter. Måten å komme seg rundt dette er å pakke løftet i en funksjon som gjør det slik:
var sendEmail = funksjon (emailAddress) return new Promise (funksjon (løse, avvise) // Foreløpig å sende en e-post // eller gjøre noe annet asynkront setTimeout (funksjon () løse ('Send til epost + + emailAddress); , 3000);); ;
Vi bruker setTimeout
ring her for å bare falle en oppgave som tar noen sekunder å kjøre asynkront.
Så hvordan bruker vi vår nye løfteskapende funksjon? Vel, siden hver Løse
funksjon som brukes innenfor a deretter
bør returnere en funksjon, så kan vi bruke den på samme måte som synkronte oppgaver.
myPromise .then (funksjon (resultat) return JSON.parse (result);) .then (funksjon (parsedJSON) return parsedJSON.email.toLowerCase ();) .then (funksjon (emailAddress) return sendEmail (emailAddress )) .then (funksjon (resultat) // Outputs "Epost sendt til [email protected]" console.log (result);, funksjon (err) console.error (err););
La oss gå over denne flytningen bare for å oppsummere hva som skjer. Vårt opprinnelige løfte myPromise
ber om et stykke JSON. Når det JSON er mottatt (vi vet ikke når), setter vi JSON inn i et JavaScript-objekt og returnerer den verdien.
Når det er gjort, tar vi e-postadressen ut av JSON og gjør den små bokstaver. Så sender vi en e-post til den adressen, og igjen vet vi ikke når den skal fullføre, men når den gjør det, sender vi en suksessmelding til konsollen. Ingen tung nesting i sikte.
Jeg håper dette har vært en nyttig introduksjon til løfter, og har gitt deg god grunn til å begynne å bruke dem i JavaScript-prosjektene dine. Hvis du vil lære mer om løfter i større detalj, sjekk ut Jake Archibalds utmerkede HTML5 Rocks-artikkel om dette emnet.
Lær JavaScript: Den komplette veiledningen
Vi har bygget en komplett guide for å hjelpe deg med å lære JavaScript, enten du er bare i gang som webutvikler eller du vil utforske mer avanserte emner.