Păstrarea de promisiuni cu JavaScript

JavaScript, prin popularitatea și îmbunătățirile recente, devine din ce în ce mai bun prieten al celui mai bun web programator. Și ca toți cei mai buni prieteni, JavaScript își păstrează promisiunile. 

Acum suna cam ciudat, dar este adevărat. Cele mai multe browsere actuale acceptă ceea ce se numește obiectul Promise. O promisiune este ca o funcție în sensul că reprezintă o bucată de cod sau o sarcină pe care ați dori să o executați la un moment dat în viitor.

Iată ce arată o promisiune.

var myPromise = promisiune nouă (funcție (rezolvare, respingere) // Activitatea de efectuat merge aici.);

Puteți vedea aici că atunci când creăm o promisiune, îi dăm un singur argument, care este o funcție care conține un cod pe care ne-ar plăcea să îl executăm la un moment dat în viitor. S-ar putea să fi observat, de asemenea, cele două argumente în funcția trecută la promisiune, rezolva și respinge. Acestea sunt și funcții și sunt modul nostru de a spune Promisiunea dacă a făcut ceea ce a promis să facă. Acesta este modul în care le veți folosi:

var myPromise = new Promise (functie (rezolvare, respingere) if (true) resolve ('Hello Tuts + fani!') else respinge ('Aww, didn`t work.');

Această promisiune va fi, evident, întotdeauna soluționată ca fiind dacă declarația va fi întotdeauna adevărată. Aceasta este doar pentru scopuri de învățare - vom face ceva mai realist mai târziu - dar imaginați-vă înlocuirea Adevărat cu un fragment de cod pe care nu erați 100% sigur că va funcționa.

Acum, când am creat o promisiune, cum îl folosim? Ei bine, trebuie să-i spunem ce anume rezolva și respinge funcțiile sunt. Noi facem asta folosind promisiunea atunci metodă.

myPromise.then (funcția (rezultatul) // Rezolvarea apelului de apel, console.log (rezultat);, funcția (rezultatul) // Respingerea apelului de apel, console.error (rezultat);

Deoarece instrucțiunea noastră dacă trece mereu Adevărat verificați, codul de mai sus va înregistra mereu "Fanii Hello Tuts +!" la consola. De asemenea, o va face imediat. Acest lucru se datorează faptului că codul din constructorul promisului nostru este sincron, ceea ce înseamnă că nu așteaptă nici o operație de executat. Are toate informațiile necesare pentru a continua și o face cât mai curând posibil. 

Totuși, în cazul în care promite într-adevăr straluceste, este atunci când vine vorba de sarcini asincrone - sarcini în care nu știți când exact promisiunea va fi îndeplinită. Un exemplu real al unei sarcini asincrone este de a prelua o resursă, cum ar fi un fișier JSON, de exemplu, prin AJAX. Nu știm cât timp serverul va lua pentru a răspunde și poate chiar nu reușește. Să adăugăm în AJAX codul de promisiune.

var myPromise = new Promise (functie (rezolvare, respingere) // AJAX cerere standard si sarcina var request = new XMLHttpRequest (); // Request a comment utilizator de la blogul nostru fals request.open (' http://jsonplaceholder.typicode.com/posts/1 '); // Setați funcția de a apela atunci când este încărcată resursa. request.onload = function () if (request.status === 200) rezolva (solicita. ); altceva respinge ('Pagina încărcată, dar nu este OK');; // Setați funcția de a apela atunci când încărcarea eșuează request.onerror = function () respinge ('Aww, lucrați la toate. '); request.send (););

Codul de aici este doar standard JavaScript pentru a efectua o cerere AJAX. Solicităm o resursă, în acest caz un fișier JSON la o adresă URL specificată și așteptăm să răspundă. Nu vom ști exact când. Și, evident, nu vrem să oprim execuția scenariului pentru a aștepta, deci ce facem? 

Din fericire, am pus acest cod într-o promisiune. Prin punerea ei aici, suntem de fapt spunând: "Hei, codul, trebuie să plec doar acum, dar vă voi da un telefon mai târziu și vă voi spune când să executați. Promiteți că veți face asta și că-mi spuneți cand esti gata?" Și codul va spune: "Da, desigur, promit." 

Un lucru important care trebuie notat în codul de mai sus este chemarea rezolva și respinge funcții. Amintiți-vă, acestea sunt modul nostru de a spune promisiunea noastră că codul nostru are sau nu a fost executat cu succes. În caz contrar, nu vom ști niciodată.

Folosind același cod din exemplul nostru de bază, putem vedea cum cererea noastră AJAX în cadrul promisiunii va funcționa acum.

// Spuneți promisiunea noastră de a vă executa codul // și spuneți-ne când sa terminat. myPromise.then (functie (rezultat) // Imprimare primite JSON in consola console.log (rezultat);, functie (rezultat) // Imprimare "Aww nu a functionat" sau " nu este ok. "console.error (rezultat););

Știam că putem avea încredere în tine, promisiunea mea.

Promisiunile de aliniere

Acum, s-ar putea să vă gândiți în acest moment că promisiunile sunt doar funcții de apel callback cu o sintaxă mai frumoasă. Asta e adevărat într-o anumită măsură, dar pentru a continua cu exemplul nostru AJAX, spuneți că trebuie să faceți mai multe cereri, fiecare cerere bazată pe rezultatul ultimului. Sau dacă ar fi trebuit să procesăm primul JSON? 

Făcând acest lucru cu callbacks se va termina în cuiburi grele de funcții, fiecare dintre care devine din ce în ce mai greu de urmărit. Din fericire, în lumea promisiunilor, putem asocia astfel de funcții împreună. Iată un exemplu în care odată ce primim JSON-ul pentru comentariul unui utilizator pe blogul nostru fals, atunci vrem să ne asigurăm că este vorba cu litere mici înainte de a face altceva cu el.

MyPromise .then (functie (rezultatul) // Odata ce primim JSON, transformam-o intr-un obiect JSON si intoarcem returnul JSON.parse (rezultat);)) .then (function (parsedJSON) a fost parsată, / / ​​a primit adresa de e-mail și a făcut-o cu litere mici. return parsedJSON.email.toLowerCase ();)) .then (funcția (emailAddress) // După ce textul a fost făcut cu litere mici, // tipăriți-l în consola. console.log (emailAddress);, funcția (err) // Ceva din lanțul de mai sus a greșit? // Imprimare ieșire respingere console.error (err);

Puteți vedea aici că, în timp ce apelul nostru inițial a fost asincron, este posibil să lanseze și apelurile sincrone. Codul în fiecare rezolva funcția în interiorul atunci va fi chemat când fiecare se întoarce. De asemenea, veți observa că există o singură funcție de eroare specificată aici pentru întregul lanț. Plasând acest lucru la sfârșitul lanțului ca respinge funcția în ultima atunci, orice promisiune din lanțul care cheamă respinge o vom suna pe asta.

Acum, că suntem puțin mai încrezători cu promisiunile, să creăm un altul împreună cu cel de mai sus. Vom crea unul care va lua adresa nouă de e-mail minuscule și va (pretinde că) trimite un e-mail la acea adresă. Acesta este doar un exemplu pentru a ilustra ceva asincron - ar putea fi orice, cum ar fi contactarea unui server pentru a vedea dacă e-mailul era pe un whitelist sau dacă utilizatorul este conectat. Trebuie să dăm adresa de e-mail nouă promisiune, dar promisiunile nu acceptă argumente. Modalitatea de a obține acest lucru este de a împacheta promisiunea într-o funcție care face, cum ar fi:

var sendEmail = functie (emailAddress) retur noi Promise (functie (rezolvare, respingere) // Pretindeti sa trimiteti un e-mail // sau sa faceti altceva asincron setTimeout (function () resolve ('Email trimis la' + emailAddress); , 3000);); ;

Folosim setTimeout sunați aici pentru a falsifica pur și simplu o sarcină care durează câteva secunde pentru a rula în mod asincron.

Deci, cum să folosim noua noastră funcție de creare de promisiuni? Ei bine, din moment ce fiecare rezolva funcția folosită în cadrul unui atunci ar trebui să returneze o funcție, atunci o putem folosi într-un mod similar sarcinilor noastre sincrone.

MyPromise .then (functie (rezultatul) return JSON.parse (rezultat);) .then (functie (parsedJSON) return parsedJSON.email.toLowerCase (); .then (function (emailAddress) retur sendEmail )) .then (functie (rezultat) // Outputs "E-mail trimis la [email protected]" console.log (rezultat);, functie (err) console.error (err);

Să trecem peste acest flux doar pentru a rezuma ce se întâmplă. Promisiunea noastră inițială promisiunea mea solicită o bucată de JSON. Când se recepționează JSON (nu știm când), transformăm JSON-ul într-un obiect JavaScript și returnez acea valoare. 

După ce sa terminat, luăm adresa de e-mail din JSON și o facem cu litere mici. Apoi trimitem un e-mail la acea adresă și, din nou, nu știm când va termina, dar când o face, vom transmite un mesaj de succes consolei. Nu există cuiburi grele în vedere.

Concluzie

Sper că aceasta a fost o introducere utilă în Promises și ți-a dat un motiv bun să începi să le folosești în proiectele tale JavaScript. Dacă doriți să aflați mai multe despre Promisiuni în detaliu, verificați articolul HTML5 Rocks excelent al lui Jake Archibald despre acest subiect.

Aflați JavaScript: Ghidul complet

Am creat un ghid complet care vă ajută să învățați JavaScript, indiferent dacă începeți doar ca dezvoltator web sau doriți să explorați subiecte mai avansate.

Cod