This kind of callback function have the error as the first parameter and the actual value as the second
function incrementAndLog(err, value) {
if (err) {
console.log("there's no value to increment");
return;
}
console.log(value + 1);
}
The caller function will call the callback by setting the first parameter if there's some error or the second one to give the result.
function paranoidDivisionMax100(x, y, cb) {
if (y < 1) {
return cb("y should be greater than zero");
}
if (y > 100) {
return cb("y should be less than 101");
}
return cb(null, x / y);
}
So if we call
paranoidDivisionMax100(8, 2, incrementAndLog)
It will print the 5 value, but if we call:
paranoidDivisionMax100(8, 0, incrementAndLog)
it will print "there's no value to increment"
We can also take care of some errors and let a outer function to handle the others.
function calculate(x, y, next) {
return paranoidDivisionMax100(x, y, (err, result) => {
if (err === "y should be greater than zero") {
console.log(err);
return;
}
if (err) {
return next(err);
}
return result;
});
}
Here we propagate the unexpected errors through the next
callback that could be defined as:
function handleWeirdError(err) {
console.log(`Ups we had a weird error: ${err}`);
return;
}
We can still use the built in try
and catch
to handle any exeption thrown on the callbacks code
By using generators we can pause the function execution while we wait for an asynchronous operation to finish. There are some libraries that help us to intercept callbacks an resume the execution when the result is ready like Suspend.
Using our function paranoidDivisionMax100
we could write this.
// Import the Suspend library
var suspend = require('suspend');
suspend(function*(resume) {
// We will wait until the function 'resume' call next() to
// continue with the execution after the callback function is done.
var data = yield paranoidDivisionMax100(8, 2, resume);
// The first element of the list contains the error if any
if(data[0]) {
throw data[0];
}
// The second element contains the actual result
console.log(data[1]);
})();