When working with promises in JavaScript, we have a possibility to use .then
, .catch
and .finally
. Each of these methods returns a new Promise
object.
Using .then
is pretty straightforward - we chain them. The use case for finally - is to put it at the end of the chain of .then
and .catch
. But
In the code below, as I understand, we initialize promise p
which can resolve or reject. I could use .then(resolutionHandler, rejectionHandler)
, which would be self-explanatory as it's only 1 .then
"handler" with both handlers, but in case of sequencing .then
and .catch
instead of the latter approach-
**Are .then
and .catch
handlers somehow paired and treated like .then(resolutionHandler, rejectionHandler)
? or something else is happening? **
const p = new Promise((resolve, reject) => {
reject("ups...");
});
p
.then(data => {
// this is success handler for Promise "p"
})
.catch(err => {
// Is this failure handler for Promise "p"?
})
Not exactly. When you have p.then(handleThen).catch(handleCatch)
, if p
rejects, handleCatch
will handle it. But handleCatch
will also handle errors thrown by handleThen
.
Although those sorts of errors are pretty unusual with if handleThen
contains only synchronous code, if handleThen
returns a Promise, handleCatch
will be able to handle that Promise if it rejects.
<somePromiseChain>
.catch(handleCatch);
will have the handleCatch
handle any errors thrown anywhere in the above Promise chain.
In contrast, with p.then(resolutionHandler, rejectionHandler)
, the rejectionHandler
will only handle a rejection of p
. It will completely ignore anything that occurs in resolutionHandler
.
If the resolutionHandler
is completely synchronous, doesn't return a Promise, and never throws (which is pretty common), then .then(resolutionHandler, rejectionHandler)
is indeed equivalent to.then(resolutionHandler).catch(rejectionHandler)
. But it's usually a good idea to use .then(..).catch(..)
.
With p.then(success).catch(fail)
, the .catch
is actually attached to the Promise returned by the .then
- but if p
rejects, the .then
's Promise rejects as well, with the same value as p
's rejection. It's not that the catch
is attached directly to p
, but it's attached to a .then
which passes p
's rejection through.
Every .then
/ .catch
is attached directly to the upper Promise it's called on, but sometimes that upper Promise passes through the value from its upper Promise unaltered. That is. p.then(undefined, fail).then(success)
will run success
if p
resolves, with the intermediate .then
passing the resolution through. With rejection, p.then(success).catch(fail)
will run fail
because the .then(success)
passes the failure from p
through unaltered.