包装 node.js 同步函数是否使其执行与其等效的异步函数相同?

Does wrapping a node.js sync function make it perform the same as its async equivalent?

没有错误处理的简单示例:

var fs = require('fs');

function read(filename, cb) {
  return cb(fs.readFileSync(filename));
}

就事件循环而言,这在性能方面是否相同,如:

fs.readFile(filename, cb);

我问的原因是加密库中的一些异步函数仍然会抛出错误,而不是将它们传递给回调。我只想制作一个自定义异步函数,按照我想要的方式处理错误,但担心使用本地方法的同步版本,因为它们在节点社区中因性能不佳而声名狼藉。那么,按照我提出的方法通过只创建一个包装函数来解决这个问题是否安全?

没有

异步的全部意义在于,由 readFileSync() 完成的实际工作发生在 事件循环之外

调用同步函数并使其异步是完全不可能的。

您不能以任何方式使异步函数在本机 node.js 中突然同步运行(例如,不创建另一个进程或使用执行某些线程的第三方库)。就是做不到。

这对你一点帮助都没有:

function read(filename, cb) {
  return cb(fs.readFileSync(filename));
}

它只是实现了一个同步回调,并没有真正解决任何问题。代码仍然全部是同步的,因此您可以获得 none 异步 I/O 的好处。重要的异步 I/O 好处是您希望主 JS 事件循环不等待文件 I/O 发生。您希望 node.js 事件循环能够在文件 I/O 以本机代码发生时执行其他操作。只要您使用 fs.readyFileSync(),无论您在其周围放置什么,都不会出现这种情况。


如果您有一些同步抛出异常而不是将错误传递给它们的回调的异步加密方法,那是设计不佳的代码,即使使用该代码我也会三思而后行。

但是,您可以通过将加密函数包装在您自己的 try catch 处理程序中来解决这个问题,如果抛出错误,该处理程序将调用回调。

假设您有这样的加密函数:

function badCryptoFunc(arg1, arg2, callback)

你可以这样包装:

function myCryptoFunc(arg1, arg2, callback) {
    try {
        badCryptoFunc(arg1, arg2, callback);
    } catch(e) {
        callback(e);
    }
}

如果函数异步抛出,那么即使这样也不会捕获异常并且代码很糟糕并且不能安全使用因为在大多数情况下在它被调用之前没有办法捕获异步异常系统,而不是您的代码。