then(..) takes one or two parameters, the first for the fulfillment
callback, and the second for the rejection callback. If either is
omitted or is otherwise passed as a non-function value, a default
callback is substituted respectively. The default fulfillment callback
simply passes the message along, while the default rejection callback
simply rethrows (propagates) the error reason it receives. catch(..)
takes only the rejection callback as a parameter, and automatically
substitutes the default fulfillment callback, as just discussed. In other words, it’s equivalent to then(null,..) :
p . then ( fulfilled );
p . then ( fulfilled , rejected );
p . catch ( rejected ); // or `p.then( null, rejected )`
then(..) and catch(..) also create and return a new promise, which can
be used to express Promise chain flow control. If the fulfillment or
rejection callbacks have an exception thrown, the returned promise is
rejected. If either callback returns an immediate, non-Promise,
non-thenable value, that value is set as the fulfillment for the
returned promise. If the fulfillment handler specifically returns a
promise or thenable value, that value is unwrapped and becomes the
resolution of the returned promise.
—from "You Don't Know JS, Kyle Simpson