14

我们正在与 node 合作,主要是为了一个内部项目,并了解使用该技术的最佳方式。

不是来自特定的异步背景,学习曲线可能是一个挑战,但我们正在习惯框架并学习过程。

让我们两极分化的一件事是使用同步代码与异步代码的最佳时间是什么时候。我们目前使用的规则是,如果有任何东西与 IO 交互,那么它必须通过回调或事件发射器(这是给定的)异步的,但其他不以任何方式使用 IO 的项目可以构造为同步函数(这will 也取决于函数本身的重量以及它实际上是如何阻塞的)但这是使用 Node.js 时采用的最佳方法吗?

例如,我们正在创建一个 Hal+JSON 构建器,它当前存在于我们的代码库中。它是同步的,因为它所做的只是创建一些相当小的对象文字,仅此而已,没有外部依赖项,当然也没有 IO 交互。

我们的方法是好还是不好?

4

3 回答 3

18

假设您有两个同步执行的函数foobar

function foo() {
    var returnValue = bar();
    console.log(returnValue);
}

function bar() {
    return "bar";
}

为了使 API “异步”是改变它使用回调:

function foo() {
    bar(function(returnValue) {
        console.log(returnValue);
    });
}

function bar(callback) {
    callback("bar");
}

但事实是,这段代码仍然是完全同步的。回调在同一个调用堆栈上执行,并且没有进行线程优化,没有可伸缩性优势。

然后它变成了代码可读性和编码风格的问题。我个人发现典型的var val = func();类型代码更具可读性和易于理解。唯一的缺点是,如果有一天你需要更改barso 的功能,它需要执行一些 I/O 活动或调用其他异步函数,你也需要更改 API bar

个人的偏好:在适用时使用传统的同步模式。当涉及 I/O 或有疑问时,请始终使用异步样式。

于 2012-12-13T11:51:47.657 回答
3

使用 process.nextTick() 将同步函数转换为异步函数是一种选择,但仅当您的软件阻塞时间过长时才应使用该函数。每次同步函数运行时,节点都不能做任何其他事情,因为它是单线程的。这意味着如果您的应用程序是服务器,它将变得无响应。

在拆分任何同步函数之前,我建议先进行一些基准测试和分析,以便您做出明智的决定。否则你冒着过早优化的风险

请参阅此处进行良好的讨论https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil

这是您如何使您的函数异步的方法,从某种意义上说,您将允许节点做其他事情http://howtonode.org/understanding-process-next-tick

于 2012-12-13T12:00:26.880 回答
1

我不知道什么是“Hal+Json builder”,但这就是我对 NodeJS 的看法。您应该尽可能异步地编写代码,将其推向极限。原因很简单,异步代码以性能换取响应性,这在大多数情况下更为重要。

当然,如果某些操作真的很快,那么就不需要异步代码。例如考虑以下代码:

var arr = []; // assume array is nonempty
for (var i = 0, l = arr.length; i < l; i++) {
    arr[ i ].doStuff( );
}

如果arr很小并且doStuff是快速操作,那么您不应该以异步方式编写此代码。但是,如果需要一些时间,那么你应该考虑这样写:

var arr = []; // assume array is nonempty
var process_array_element = function( ) {
    if (arr.length) {
        arr.pop().doStuff( );
        process.nextTick( process_array_element );
    }
};
process_array_element( );

现在这段代码是真正异步的。它需要更多时间才能完成这项工作,但同时它不会阻塞整个服务器。我们用性能换取了响应能力。

结论:这取决于你的情况!:)

于 2012-12-13T11:54:57.207 回答