我正在编写一个 node.js 插件来执行一些加密计算,这可能需要大约 1 μs – 20 μs。现在我有一个选择:将其实现为同步方法或异步方法(在后台工作人员上进行计算)?
很明显,有时需要超过一毫秒的网络和 I/O 应该异步完成。解析 JSON 输入速度很快,并且应该同步完成。
在我的情况下,保持低延迟很重要,但优化微秒感觉很像过早优化。因此,考虑到这一背景,我有兴趣了解您对这个问题的看法:
使用 Node.js 时,(同步)调用必须阻塞多长时间,直到您决定在后台线程上异步运行它?
最佳答案
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 密集型操作,您需要使用异步操作。我想说,任何 CPU 密集型逻辑都不应该在阻塞事件循环的主线程中完成,而应该在外部进程或工作线程中完成,或者在从 C++ 生成的线程中完成,以使其最大化对用户透明。
看看它是如何在 bcrypt
和 bcrypt-nodejs
中完成的:
如果你可以让你的函数异步工作(不仅是使用回调,而且实际上不阻塞事件循环),那么我建议至少制作两种 API - 一个接受回调的函数和一个函数返回一个 promise (实际上可以是一个函数)。
目前,通过 async/await,您可以使用任何返回 Promise 的函数,几乎就像同步一样:
let x = await f();
let y = await g(x);
// ...
但在某些情况下,您需要真正的同步函数,例如您想要可以直接从模块导出的内容:
module.exports = f();
这里,当 f()
函数阻塞时,没有什么害处,因为 require()
本身也阻塞,并且您应该在启动期间只使用它一次。但是,如果该函数是异步的 - 通过使用 async
关键字声明,从而隐式返回一个 Promise,通过显式返回一个 Promise 或通过回调,那么您将无法从一个模块并以某些方式使用它。
因此,如果您认为函数的返回值可以从模块导出是有意义的,那么您可能还需要提供一个阻塞的同步版本。
关于javascript - NodeJS什么时候选择同步计算延迟太大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43980604/