NodeJS:在 async/await 中使用回调函数或同步函数更好吗?

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

我目前正在将我项目的一些依赖项转换为它们自己的异步/等待函数,以实现更好的开发流程。其中许多依赖项(例如 bcrypt)具有使用同步(无回调)函数或异步(回调)函数的选项。我做了一个超小的函数,可以将 bcrypt 的输出转换为我的框架友好版本,该版本总是 returns {success: true/false, result} 对象。这是我所拥有的示例。

      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}
        }
      },
    

问题是,bcrypt 提供了两个用于比较字符串和散列字符串的函数;比较同步和比较。如果我将代码格式化为使用使用回调的比较函数,它将如下所示:

       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' })
           })
         })
        }

我的目标确实是将每个带有回调的函数都转换为基于承诺的格式,但我的问题是这样的;您认为以上哪一项总体上对性能更友好?从技术上讲。这两个函数都是异步的,但您认为哪个更快?

如果我构建这段代码的方式看起来不合逻辑,请告诉我。我不确定这是否是格式化不间断代码的最佳方式,所以我希望收到有关此的任何反馈。

感谢您花时间阅读本文。如果您有任何建议,我将不胜感激。

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

您想使用函数的异步版本,因为同步版本会阻塞并且不能异步使用。 (我所说的“阻塞”是指它们导致执行线程挂起,直到读取它们的结果,所以它们根本不是异步的。)

我相信 bcrypt 库的异步函数——就像现在的许多库一样——可以让你省略回调参数。如果您省略回调,函数 return 一个 Promise,然后您可以将其与 await 一起使用。因此,例如:

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

这里的函数是异步执行的,但它看起来像一个同步调用,因为你使用了await。如果你没有使用 await,那么你可以直接使用 Promise,例如:

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

但是 await 向您隐藏了 Promise 并使代码看起来是同步的。

Technically. both functions are asynchronous

不,第一个函数不是异步的。将 async 放在函数前面只是让您可以在其中使用 await 语法,但第一个变体实际上是同步的。第二个变体是异步的,但您也没有利用该变体中的 async,因为您没有像我上面的示例那样使用 await。您可以从这两个变体中删除 async,什么都不会改变。

but which one do you believe is faster?

它们的速度可能相同,但如果您需要并发,这意味着如果您有许多请求需要同时发生,则需要使用调用的异步版本,因为 Javascript 只有一个线程可供您的代码使用。因此,如果您使用同步版本,该线程将阻止所有其他请求的执行。异步版本调用 Javascript 不可用的其他线程,并使许多 bcrypt 计算同时发生。