bcrypt.compare() is asynchronous, does that necessarily mean that delays are certain to happen?

Viewed 5689

I'm using the bcryptjs package to hash and compare passwords.

The compareSync method used below is synchronous and returns a boolean. It is reliable and works as expected.

let trueOrFalse = bcrypt.compareSync('abcd', '1234');

if(trueOrFalse) {
    console.log('hooray, it was true');
} else {
    console.log('oops, it was false');
}

The next example uses the asynchronous compare method. I'm concerned that because this version is async if there is any delay on the server it may get to the if/else statement before bcrypt.compare has determined the value of res. Is this a valid concern or am I misunderstanding the nature of this type of async function?

let trueOrFalse;
bcrypt.compare('abcd', '1234', function(err, res) {
    trueOrFalse = res;
}

if(trueOrFalse) {
    console.log('hooray, it was true');
} else {
    console.log('oops, it was false');
}
2 Answers

Asynchronous method will be executed in parallel with your main program, so your console.log will be done before the callback function inside bcrypt.compare. You will see always 'oops, it was false'.

You can wait for the real result in your main function and then show something in console.

To make comparison 'waitable' you can wrap it into Promise:

function compareAsync(param1, param2) {
    return new Promise(function(resolve, reject) {
        bcrypt.compare(param1, param2, function(err, res) {
            if (err) {
                 reject(err);
            } else {
                 resolve(res);
            }
        });
    });
}

const res = await compareAsync(param1, param2);
console.log(res);

I prefer to wrap legacy callback functions into Promises because it will save an app from a callback hell.

The Node.js runtime will surely run the synchronous code (the if-else statements) before you get the result from the async computation. You are guaranteed that the computation is completed only in the callback function:

bcrypt.compare('abcd', '1234', function(err, res) {
    // make your checks here
    if (res) {
      // ...
    }
})
Related