Uvod v promise v JavaScriptu

Že veste, da uporaba callback modela asinhronskosti zlahka vodi v situacijo callback hell. Zato so v JavaScript uvedli nov model imenovan promise (promise). Poglejmo si ta model.

Promise predstavlja objekt, v katerega se kot parameter posreduje funkcija, znotraj katere je treba postaviti naš asinhroni kode:

javascriptlet promise = new Promise(function() {
  // asinhroni koda
});

Kot vidite, sem zabeležil objekt s promise v spremenljivko promise. Na drugem mestu kode lahko uporabim za to spremenljivko metodo then, tako da ji posredujem funkcijo s kodo, ki naj se izvede ob zaključku asinhrone kode, napisane pri ustvarjanju tega promise.

javascriptpromise.then(function() {
  // izvede se ob zaključku asinhrone kode
});

Sliši se zapleteno, zato poglejmo primer. Recimo, da imam takšen asinhroni koda:

javascriptsetTimeout(function() {
  let result = [1, 2, 3, 4, 5];
}, 3000);

Recimo, da želim rešiti zanj našo glavno nalogo asinhronskosti: izvesti neko kodo po sprožitvi časovnika. Pri tem nočem postaviti te kode v časovnik sam in želim, da v to kodo nekako pride rezultat, ki sem ga zapisal v spremenljivki result. V bistvu smo to nalogo reševali v prejšnjih lekcijah s callbacki in naročninami. Poglejmo zdaj, kako to narediti z promise.

Za začetek je treba naš asinhroni koda zaviti v promise:

javascriptlet promise = new Promise(function() {
  setTimeout(function() {
    let result = [1, 2, 3, 4, 5];
  }, 3000);
});

Toda tega ni dovolj. Moramo eksplicitno navedeti, da se je naš asinhroni koda zaključil. Pri tem nam bo pomagala posebna funkcija zaključka, ki samodejno pride v prvi parameter funkcije, če je naveden:

javascriptlet promise = new Promise(function(resolve) { // navedemo parameter
  setTimeout(function() {
    let result = [1, 2, 3, 4, 5];
  }, 3000);
});

Z funkcijo zaključka lahko eksplicitno obvestimo promise, da se je asinhroni koda zaključil. Za to moramo to funkcijo poklicati na ustreznem mestu:

javascriptlet promise = new Promise(function(resolve) {
  setTimeout(function() {
    let result = [1, 2, 3, 4, 5];
    resolve(); // zaključimo promise
  }, 3000);
});

Če želimo navzven poslati kakšen rezultat asinhrone kode, ga lahko posredujemo kot parameter naši funkciji zaključka:

javascriptlet promise = new Promise(function(resolve) {
  setTimeout(function() {
    let result = [1, 2, 3, 4, 5];
    resolve(result); // posredujemo rezultat
  }, 3000);
});

Seveda se lahko znebimo vmesne spremenljivke:

javascriptlet promise = new Promise(function(resolve) {
  setTimeout(function() {
    resolve([1, 2, 3, 4, 5]);
  }, 3000);
});

Zdaj lahko kjer koli drugje pokličemo metodo then našega promise:

javascriptpromise.then(function() {
  // sproži se ob zaključku promise
});

Rezultat delovanja promise bo prišel v prvi parameter funkcije, če ga želimo navesti:

javascriptpromise.then(function(result) {
  console.log(result); // izpiše matriko z rezultatom
});
Задание 1

Naredite promise, znotraj katerega bo zakasnitev 5 sekund, nato pa se mora promise izpolniti, tako da vrne kakšno besedilo kot rezultat. Izpišite to besedilo na zaslon.