NodeJS什么时候选择同步计算延迟太大?

When is delay too large for choosing synchronous calculation in NodeJS?

我正在编写一个 node.js 插件来执行一些密码计算,这可能需要大约 1 μs – 20 μs。现在我有一个选择:将其实现为同步方法或异步方法(在后台工作程序上进行计算)?

很明显,网络和 I/O,有时需要的时间超过一毫秒,应该异步完成。解析 JSON 输入很快,应该同步完成。

在我的情况下,保持低延迟很重要,但优化微秒感觉很像过早优化。因此,考虑到这种情况,我很想听听您对这个问题的看法:

使用 node.js 时,(同步)调用必须阻塞多长时间,直到您决定在后台线程上异步 运行 它?

为什么不将其实现为同步方法和异步方法,其中包含 cryptAsync()cryptSync() 等 2 个函数?我觉得你做起来比较好,也不难。

It is obvious that network and I/O, which sometimes takes longer than a millisecond should be done asynchronously. Parsing JSON input is fast and should be done synchronously.

这不是很明显。 Node.js 有异步 JSON 解析器。参见:

但确实在某些时候对于 CPU 密集型操作您需要使用异步操作。我会说 any CPU 密集型逻辑不应该在阻塞事件循环的主线程中完成,而应该在外部进程或工作线程中完成,或者在线程中完成从 C++ 衍生出来,使其对用户最大程度地透明。

bcryptbcrypt-nodejs 中查看它是如何完成的:

如果你可以让你的函数异步工作(不仅在使用回调的意义上,而且实际上不阻塞事件循环)那么我建议至少制作两种 API - 一个接受回调的函数和一个函数 return 承诺(实际上可以是一个函数)。

目前 async/await 您可以使用任何 return 承诺的函数,就好像它是同步的一样:

let x = await f();
let y = await g(x);
// ...

但在某些情况下,您需要一个真正同步的函数,例如,如果您想拥有可以直接从模块中导出的内容:

module.exports = f();

这里,当 f() 函数被阻塞时,没有什么坏处,因为 require() 本身也是阻塞的,你应该只在启动期间使用它一次。但是,如果该函数是异步的——通过使用 async 关键字声明并因此隐式 return 承诺,通过显式 return 承诺或采用回调,那么您将不会能够从模块导出值并以特定方式使用它。

因此,如果您认为函数的 return 值可以从模块中导出是有意义的,那么您可能还需要提供一个阻塞的同步版本。