Изузеци у ланцима промиса у JavaScript-у

Нека из неких разлога наш промис заврши са грешком:

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

У том случају извршавање кода ће одмах прећи на онај then у коме постоји функција-обрађивач грешке, или на први catch, зависно шта се раније наиђе.

Ево примера прве ситуације:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  },
  function(error) {
    // извршавање ће одмах прећи овде
  }
).then(
  function(result) {
    console.log(result);
  }
);

Ево примера друге ситуације:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    // извршавање ће одмах прећи овде
  }
).then(
  function(result) {
    console.log(result);
  }
);

Функција-обрађивач има две опције: ако је успела да реши изузетну ситуацију, може да врати резултат преко return и извршавање ће наставити даље низ ланац. Ако није успела да реши грешку, може или да не врати ништа, или да баци изузетак преко throw. У том случају извршавање ће прећи на следећи хватач грешке (у then или catch - шта год се раније наиђе).

Обично, све грешке ланца се хватају на једном месту: на крају ланца се поставља catch:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    // доћи ћемо овде у случају грешке
  }
);

При том изузетак може настати у самом промисе, или бити бачен преко throw у било ком звену ланца:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    if (sveJeUredu) {
      return result + '2';
    } else {
      throw new Error('greška'); // прелазимо на најближег хватача
    }
  }
)
.then(
  function(result) {
    return result + '3';
  }
).catch(
  function(error) {
    // најближи хватач
  }
);

Имајте у виду да је catch потребан управо за дијагностику грешке: да ли је решива или не. Ако је грешка решива, онда catch треба да проследи њено решење следећем then иза себе. А ако није решива (или овај catch једноставно не зна како да је реши), онда морамо или да не вратимо ништа или да бацимо изузетак:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    if (greskaJeResiva) {
      return 'podaci'; // шаљемо на следећи then
    } else {
      // не враћамо ништа или бацамо изузетак
    }
  }
).then(
  function(result) {
    // овде решавамо грешку
  }
);