bcrypt.compare() 或 bcrypt.compareSync()
Posted
技术标签:
【中文标题】bcrypt.compare() 或 bcrypt.compareSync()【英文标题】:bcrypt.compare() or bcrypt.compareSync() 【发布时间】:2021-11-18 06:40:19 【问题描述】:我有一个关于这个话题的问题: bcrypt.compare() is asynchronous, does that necessarily mean that delays are certain to happen?
由于我的会员级别不允许我发布 cmets,我不得不打开新主题。
我的问题是有什么缺点,或者使用bcrypt.compareSync()
代替异步版本的bcrypt.compare()
有什么缺点。
compareSync()
肯定会给出正确的结果。那么为什么不使用它并使用包装在 Promises 中的 compare()
呢?它会停止 nodeJS 为其他用户提供服务吗?
【问题讨论】:
【参考方案1】:项目的自述文件中很好地解释了使用异步方法而不是同步方法的原因。
为什么推荐异步模式而不是同步模式?
如果你在一个简单的脚本上使用 bcrypt,使用同步模式是非常好的。但是,如果您在服务器上使用 bcrypt,则建议使用异步模式。这是因为 bcrypt 完成的散列是 CPU 密集型的,因此同步版本将阻止事件循环并阻止您的应用程序为任何其他入站请求或事件提供服务。异步版本使用线程池,不会阻塞主事件循环。
https://github.com/kelektiv/node.bcrypt.js#why-is-async-mode-recommended-over-sync-mode
因此,如果您在 web 应用程序或其他不想阻塞主线程的环境中使用它,您应该使用异步版本。
【讨论】:
是的,我知道这一点。我要问的是事件循环是否被阻止 - 这不是问题,因为用户尚未登录 - 对于该特定用户或正在访问该应用程序的所有其他人? 节点中只有一个事件循环,它将服务于Web应用程序中的所有请求,因此如果它被阻塞,那么它会被所有人阻塞。 谢谢,这是我想知道的。【参考方案2】:Node.js 原生方法具有 Sync 附加方法,例如 fs.writeFileSync
、crypto.hkdfSync
、child_process.execSync
。浏览器中的 javascript 与所有需要线程阻塞的原生函数异步实现,但 Node.js 中的 Sync 方法实际上会阻塞线程,直到任务完成。
在Node.js中使用Callback
或Promise
时,如果内部只执行异步逻辑,则可以在不停止主线程的情况下管理异步任务,同时进行其他任务(使用Callbak
的计数, Promise.all
)。
Sync 方法在工作后运行下一行,因此易于识别执行顺序,易于编码。但是,主线程被阻塞了,因此您一次只能执行一项任务。
想想下一个例子。
const syncFunc = () =>
for (let i = 0; i < 100; i++) fs.readFileSync(`/files/$i.txt`);
console.log('sync done');
;
const promiseFunc = async () =>
await Promise.all(Array.from(length: 100, (_,i) => fs.promises.readFile(`/files/$i.txt`)));
console.log('promise done');
;
当读取所有 100 个 txt 文件没有问题时,promise 函数结束得更快。
此同步功能同样适用于由 C 语言制成的库。如果你看下面的代码,你可以看到在 C++ 中实现的不同。
compare compareSync总之,我认为这是一个选择问题。如果您编写的代码是在单个线程上运行的逻辑,则使用 Sync 方法没有问题,如果主线程被阻塞(如简单宏),则无关紧要。但是,如果您正在做的逻辑是服务器等性能问题很重要,并且主线程不应该尽可能停止线程或异步管理,您可以选择Promise
或Callback
。
【讨论】:
以上是关于bcrypt.compare() 或 bcrypt.compareSync()的主要内容,如果未能解决你的问题,请参考以下文章
bcrypt.compare() 是异步的,这是不是一定意味着肯定会发生延迟? [复制]
bcrypt.compare() 在验证密码时总是返回 false
等待 bcrypt.compare(req.body.password, user.password) 返回 false