Hyrje në Premiset në JavaScript
Ju tashmë e dini se përdorimi i modelit të callback për asinkronizën çon lehtësisht në situatën callback hell. Prandaj në JavaScript u prezantua një model i ri i quajtur premisa (promise). Le ta studiojmë këtë model.
Një premisë përfaqëson një objekt, në të cilin si parametër kalrohet një funksion, brenda së cilës duhet të vendosim kodin tonë asinkron:
let promise = new Promise(function() {
// kod asinkron
});
Siç e shihni, unë e regjistrova objektin me premisën
në variablin promise. Në ndonjë vend tjetër
të kodit unë mund të aplikoj në këtë variabël
metodën then, duke kaluar në të një funksion
me kodin, i cili duhet të ekzekutohet pas
përfundimit të kodit asinkron, të shkruar
gjatë krijimit të kësaj premise:
promise.then(function() {
// do të ekzekutohet pas përfundimit të kodit asinkron
});
Tingëllon konfuze, prandaj le të shohim në një shembull. Le të themi se unë kam një kod asinkron të tillë:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Le të themi se unë dëshiroj të zgjidh për të detyrën tonë kryesore
të asinkronizës: të ekzekutoj një kod
pas aktivizimit të timerit. Në të njëjtën kohë
unë nuk dëshiroj ta vendos këtë kod brenda vetë timerit
dhe dëshiroj që në këtë kod të arrijë siçdoqoftë rezultati,
i shkruar nga unë në variablin result.
Në përgjithësi, ne e zgjidhëm këtë detyrë në mësimet e mëparshme
përmes callback-eve dhe abonimeve. Le të
shohim tani se si ta bëjmë këtë përmes premisave.
Fillimisht duhet ta mbështjellim kodin tonë asinkron në një premisë:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Kjo, megjithatë, nuk mjafton. Ne duhet të tregon në mënyrë eksplicite se kodi ynë asinkron ka përfunduar. Në këtë na ndihmon një funksion i posaçëm përfundimi, i cili futet automatikisht në parametrin e parë të funksionit, nëse ai është specifikuar:
let promise = new Promise(function(resolve) { // specifikojmë parametrin
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Përmes funksionit të përfundimit ne mundemi në mënyrë eksplicite të tregojmë premisës se kodi asinkron ka përfunduar. Për këtë ne duhet ta thirrim këtë funksion në vendin e duhur për ne:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // përfundojmë premisën
}, 3000);
});
Në të njëjtën kohë, nëse dëshirojmë të kalojmë jashtë ndonjë rezultat të kodit asinkron, ne mund ta kalojmë atë si parametër funksionit tonë të përfundimit:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // kalojmë rezultatin
}, 3000);
});
Mundet, sigurisht, të heqim qafe variablin e ndërmjetëm:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Tani në çdo vend tjetër ne mund të thërrasim
metodën then të premisës sonë:
promise.then(function() {
// do të aktivizohet pas përfundimit të premisës
});
Rezultati i punës së premisës do të hyjë në parametrin e parë të funksionit, nëse dëshirojmë ta specifikojmë atë:
promise.then(function(result) {
console.log(result); // do të shfaqë array me rezultatin
});
Krijoni një premisë, brenda së cilës do të ketë një vonesë
prej 5 sekondash, pas së cilës premisa duhet
të përfundojë, duke kthyer si rezultat ndonjë
tekst. Shfaqeni këtë tekst në ekran.