Kivételek a Promise láncokban JavaScriptben

Tételezzük fel, hogy valamilyen okból a Promise-unk hiba miatt szakad meg:

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

Ebben az esetben a kód végrehajtása azonnal ugrani fog ahhoz a then-hez, amelyben van egy hibakezelő függvény, vagy az első catch-hez, attól függően, melyik következik előbb.

Itt egy példa az első helyzetre:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  },
  function(error) {
    // a végrehajtás azonnal ide ugrik
  }
).then(
  function(result) {
    console.log(result);
  }
);

Itt egy példa a második helyzetre:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    // a végrehajtás azonnal ide ugrik
  }
).then(
  function(result) {
    console.log(result);
  }
);

A hibakezelő függvénynek két lehetősége van: ha sikerült kezelnie a kivételes helyzetet, akkor visszaadhat egy eredményt a return-nel, és a végrehajtás folytatódik a láncban tovább. Ha viszont nem sikerült kezelnie a hibát, akkor vagy nem ad vissza semmit, vagy kivételt dob a throw-nel. Ebben az esetben a végrehajtás ugrani fog a következő hibakezelőhöz (a then-ben vagy catch-ben - attól függően, melyik következik előbb).

Általában a lánc összes hibáját egy helyen kapjuk el: a lánc végén elhelyezünk egy catch-et:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    // ide érkezünk hiba esetén
  }
);

Ebben az esetben a kivétel magában a Promise-ban keletkezhet, vagy bármelyik láncszemben eldobódhat a throw-nel:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    if (mindenRendben) {
      return result + '2';
    } else {
      throw new Error('hiba'); // ugrunk a legközelebbi hibakezelőhöz
    }
  }
)
.then(
  function(result) {
    return result + '3';
  }
).catch(
  function(error) {
    // a legközelebbi hibakezelő
  }
);

Vegyük figyelembe, hogy a catch-et pontosan a hiba diagnosztizálására használjuk: megoldható-e vagy sem. Ha a hiba megoldható, akkor a catch-nek át kell adnia a megoldását a mögötte lévő then-nek. Ha pedig nem megoldható (vagy ez a catch egyszerűen nem tudja, hogyan oldja meg), akkor vagy nem adunk vissza semmit, vagy kivételt dobunk:

javascriptpromise.then(
  function(result) {
    return result + '1';
  }
).then(
  function(result) {
    return result + '2';
  }
).catch(
  function(error) {
    if (aHibaMegoldhato) {
      return 'adatok'; // továbbítjuk a következő then-nek
    } else {
      // nem adunk vissza semmit vagy kivételt dobunk
    }
  }
).then(
  function(result) {
    // itt oldjuk meg a hibát
  }
);