Recently I started using pg-promise with bluebird library. I have always been nesting callback and handling err
in each callback. I find that the catch
statement in promise looks really neat. I am not sure if it possible to turn this code to promise base?
username = username.toUpperCase();
let text = "SELECT * FROM users WHERE username = $1";
let values = [username];
database.one(text, values).then(function (userObject) {
// ANY WAY TO TURN this nested bycrypt into promise chain?
bcrypt.compare(password, userObject.password, function (err, same) {
if (err) {
return next(err, null);
}
if (!same) {
return next(new Error("Password mismatched!"), null);
}
const serializeObject = {_id: userObject._id};
return next(null, serializeObject);
});
}).catch(function (err) {
return next(err, null);
});
This is to extend on @Jaromanda's answer, in case you use only that one function, and just want to see how to promisify it manually.
Other than that, the
promisify
approach is the way to go. But it is always good to understand what it effectively does ;)I imagine using bluebirds promisify, you would promisify bcrypt.compare like so (you don't HAVE to use the Async part of the name)
one fix, is to use a variable that will be in scope for both .then's (but ugh)
another (in my opinion cleaner) option is a nested .then
NOTE: bluebird has a promisifyAll function ... that promisifies functions in an object, and adds (by default) the
Async
postfix to the function name - I believe you can decide on a different postfix name, but the documentation will tell you morewhen promisifying a single function, you declare the name yourself - the above could've easily been
then you would just use
trumpIsBigly
where the code hascompareAsync
A hand rolled promisified compareAsync (lifted mostly from vitaly-t's answer but with additions)
Now compareAsync will resolve to the incoming value
inValue
only if there's no error, AND same is trueWhich makes the "chain" very simple!