Izuzeci u lancima promisa u JavaScript-u

Neka iz nekih razloga naš promis završi sa greškom:

javascriptlet promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    reject('error');
  }, 3000);
});

U tom slučaju, izvršavanje koda će odmah preći onome then u kojem postoji funkcija-handler greške, ili prvom catch, šta se prvo nade.

Evo primera prve situacije:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  },
  function(error) {
    // izvršavanje će odmah preći ovde
  }
).then(
  function(result) {
    console.log(result);
  }
);

Evo primera druge situacije:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    // izvršavanje će odmah preći ovde
  }
).then(
  function(result) {
    console.log(result);
  }
);

Funkcija-handler ima dve mogućnosti: ako je rešila izuzetnu situaciju, može vratiti rezultat pomoću return i izvršavanje će se nastaviti dalje niz lanac. Ako nije rešila grešku, onda može ili ništa ne vratiti, ili baciti izuzetak preko throw. U tom slučaju izvršavanje prelazi na sledeći hvatač greške (u then ili catch – šta se pre nade).

U principu, sve greške lanca se hvataju na jednom mestu: na kraju lanca se postavlja catch:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    // doći ćemo ovde u slučaju greške
  }
);

Pritom, izuzetak može nastati u samom promisu, ili bačen preko throw u bilo kom kariku lanca:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    if (sveJeUredu) {
      return result + '2';
    } else {
      throw new Error('greška'); // prelazimo na najbližeg hvatača
    }
  }
)
.then(
  function(result) {
    return result + '3';
  }
).catch(
  function(error) {
    // najbliži hvatač
  }
);

Imajte u vidu da je catch potreban baš za dijagnostiku greške: da li je rešiva ili ne. Ako je greška rešiva, onda catch treba da prosledi njeno rešenje sledećem then iza sebe. A ako nije rešiva (ili ovaj catch prosto ne zna kako da je reši), onda moramo ili ništa ne vratiti ili baciti izuzetak:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    if (greskaJeResiva) {
      return 'podaci'; // šaljemo na sledeći then
    } else {
      // ništa ne vraćamo ili bacamo izuzetak
    }
  }
).then(
  function(result) {
    // ovde rešavamo grešku
  }
);