Suppose for some reason our promise will end with an error:
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('error');
}, 3000);
});
In this case, the execution of the code
will immediately jump to then
,
which has an error handler function,
or to the first catch
, whichever
comes first.
Here is an example of the first situation:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
},
function(error) {
// an execution jumps to here
}
).then(
function(result) {
console.log(result);
}
);
Here is an example of the second situation:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// an execution jumps to here
}
).then(
function(result) {
console.log(result);
}
);
The handler function has two options: if
it handled the exception, it can return
a result via return
and execution
will continue further down the chain. If
it didn't cope with the error, then it
can either return nothing, or throw an
exception via throw
. In this case,
execution will jump to the next error
hook (at then
or catch
,
whichever comes first).
As a rule, all chain errors are caught
in one place: catch
is placed
at the end of the chain:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// we get here in case of an error
}
);
In this case, an exception can occur in
the promise itself, or thrown via
throw
in any link in the chain:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
if (everythingIsFine) {
return result + '2';
} else {
throw new Error('an error'); // we go to the nearest interceptor
}
}
)
.then(
function(result) {
return result + '3';
}
).catch(
function(error) {
// the nearest interceptor
}
);
Keep in mind that catch
is needed
specifically for diagnosing an error: is
it solvable or not. If the error is
solvable, then catch
must pass
its solution to the next then
. And
if it isn't solvable (or the given
catch
simply doesn't know how
to resolve it), then we must either
return nothing or throw an exception:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
if (errorIsSolvable) {
return 'data'; // we send it to the next then
} else {
// we return nothing or throw an exception
}
}
).then(
function(result) {
// we solve an error here
}
);