NodeJS: Are callback functions or synchronous functions better to use in async/await?

Viewed 711

Im currently in the process of converting some of my project's dependencies' to their own async / await functions for better development flow. Many of these dependencies such as bcrypt have options to use synchronous ( no callback ) functions or asynchronous ( callback ) functions. I have made a super small function that would convert the output of a bcrypt compare to my framework-friendly version that always returns a {success: true/false, result} object. Heres an example of what I have.

      async hashStringCompare (hashed, string) {
        try {
          const success = bcrypt.compareSync(string, hashed)
          if (!success) return {msg: 'The string does not match', success}
          return {msg: 'The string does match', success}
        } catch (err) {
          return {err, msg: 'Something bad happened', success: false}
        }
      },
    

The problem is, bcrypt offers two functions for comparing strings and hashed strings; compareSync and compare. If i formatted the code to use the compare function that uses callbacks, it would look like this:

       async hashStringCompare (hashed, string) {
         return new Promise((resolve) => {
           bcrypt.compare(string, hashed, (err, success) => {
             if (err) resolve({ err, msg: 'An error has occured.', success })
             resolve({success, msg: 'The string does match' })
           })
         })
        }

Really my goal is to get every function with a callback converted to a promise-based format, but my question is this; Which one of the above do you think would be overall more performance friendly? Technically. both functions are asynchronous, but which one do you believe is faster?

If the way i'm structuring this code seems illogical, please tell me. I'm not sure if this is the best way to format non-breaking code, so I would love any feedback regarding this.

Thanks for taking the time to read this. I would really appreciate any advice you may have.

1 Answers

Are callback functions or synchronous functions better to use in async/await?

You want to use the async version of the functions, because the sync versions block and can't be used asynchronously. (By "block" I mean they cause the thread of execution to be suspended until their result is read, so they are not asynchronous at all.)

I believe the bcrypt library async functions—like many libraries these days—let you omit the callback argument. If you omit the callback, the functions return a Promise, which you can then use with await. So, for example:

const result = await bcrypt.compare(string, hashed)

Here the function executes asynchronously, but it looks like a synchronous call because you used await. If you hadn't used await, then you could have used the Promise directly, like:

bcrypt.compare(string, hashed).then(result => console.log(result))

but await hides the Promise from you and makes the code look synchronous.

Technically. both functions are asynchronous

No, the first function is not asynchronous. Putting async in front of the function just enables you to use the await syntax inside of it, but that first variant is actually synchronous. The second variant is asynchronous, but you don't take advantage of async in that variant either, because you're not using await like in my example above. You can remove the async from both of those variants and nothing will change.

but which one do you believe is faster?

They're probably both the same speed, but if you need concurrency, meaning if you have many requests that need to happen at the same time, you need to use the async version of the call because Javascript only has one thread that it makes available to your code. So if you use the sync version, that thread will block execution for all other requests. The async version calls out to other threads not available to Javascript, and enable many bcrypt computations to happen concurrently.

Related