如果函数不使用任何 I/O,那么 NodeJS 异步函数的目的是什么?

What's the purpose of NodeJS async functions if the function doesn't use any I/O?

查看 NodeJS bcrypt 包 (https://www.npmjs.com/package/bcrypt),似乎有一对 async/sync:

的函数

我理解异步函数在函数具有 I/O 的情况下的目的,例如磁盘或网络访问,以免阻塞事件循环。但是对于像上面这样的情况,没有 I/O,使用异步版本有什么优势呢?

选择同步版本会损失什么?我想这样做是因为它使代码更简单,而且我看不出有任何缺点。

在 中它说 "you'd want to use the async version if possible so you're not tying up your node processing during the password hash",但是您的代码不会因为这些函数使用的是 CPU 而不是 I/O 而被捆绑吗?

如果你使用异步版本,其他代码仍然会被让给运行。例如:

异步

var startTime = new Date;

setInterval(function() {
    console.log('interval ' + (new Date - startTime));
}, 100);


setTimeout(function() {
    console.log('starting hashing');
    bcrypt.hash('bacon', 12, function (done) {
        console.log('hashing done');
    });
}, 300);

将打印:

interval 107
interval 214
starting hashing
interval 315
interval 415
interval 515
hashing done
interval 615

同步

代码的同步版本如下所示:

var startTime = new Date;

setInterval(function() {
    console.log('interval ' + (new Date - startTime));
}, 100);


setTimeout(function() {
    console.log('starting hashing');
    bcrypt.hashSync('bacon', 12);
    console.log('hashing done');
}, 300);

并输出类似

的内容
interval 105
interval 212
starting hashing
hashing done
interval 535
interval 635

我不确定它是如何在 bcrypt 模块内部完成的,也许它正在启动一个新线程,因为它是本机代码?我想您可以查看 bcrypts 源以了解详细信息。

我仔细查看了 bcrypt 的本机代码,没有发现任何可能阻塞的内容。那里的所有动作基本上都是 CPU-bound.

我认为这归结为优先级。 bcrypt 由繁重的计算函数组成。通过旋转新的执行器,它不会更快(甚至可能更慢),但至少可以在计算停止时处理其他操作。