Callbacks are often used to provide error handling. This is a form of control flow branching, where some instructions are executed only when an error occurs:
const expected = true;
function compare(actual, success, failure) {
if (actual === expected) {
success();
} else {
failure();
}
}
function onSuccess() {
console.log('Value was expected');
}
function onFailure() {
console.log('Value was unexpected/exceptional');
}
compare(true, onSuccess, onFailure);
compare(false, onSuccess, onFailure);
// Outputs:
// "Value was expected"
// "Value was unexpected/exceptional"
Code execution in compare()
above has two possible branches: success
when the expected and actual values are the same, and error
when they are different. This is especially useful when control flow should branch after some asynchronous instruction:
function compareAsync(actual, success, failure) {
setTimeout(function () {
compare(actual, success, failure)
}, 1000);
}
compareAsync(true, onSuccess, onFailure);
compareAsync(false, onSuccess, onFailure);
console.log('Doing something else');
// Outputs:
// "Doing something else"
// "Value was expected"
// "Value was unexpected/exceptional"
It should be noted, multiple callbacks do not have to be mutually exclusive – both methods could be called. Similarly, the compare()
could be written with callbacks that are optional (by using a noop as the default value - see Null Object pattern).