javascript 使用 Node.js 的同步与异步代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13858909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Synchronous vs Asynchronous code with Node.js
提问by Modika
We are working with node, mainly for an internal project and to understand the best way to use the technology.
我们正在使用 node,主要用于内部项目并了解使用该技术的最佳方式。
Not coming from a specific asynchronous background the learning curve can be a challenge but we are getting used to the framework and learning the process.
不是来自特定的异步背景,学习曲线可能是一个挑战,但我们正在习惯这个框架并学习这个过程。
One thing that has polarised us is when the best time to use synchronous code vs asynchronous code is. We are currently using the rule that if anything interacts with IO then it has to be asynchronous via call backs or the event emitter (thats a given), but other items which are not in any way using IO can be constructed as synchronous functions (this will depends as well on the heaviness of the function itself and how blocking it actually is) but is this the best approach to take when working with Node.js?
使我们两极分化的一件事是使用同步代码与异步代码的最佳时间是什么时候。我们目前使用的规则是,如果任何东西与 IO 交互,那么它必须通过回调或事件发射器(这是给定的)异步,但其他不以任何方式使用 IO 的项目可以构造为同步函数(这也取决于函数本身的重量以及它的实际阻塞程度)但这是否是使用 Node.js 时最好的方法?
For instance, we are creating a Hal+JSON builder, which currently exists within our code base. It is synchronous simply because all it is doing is creating some rather smallish object literals and nothing more, there are no external dependencies and certainly no IO interactions.
例如,我们正在创建一个 Hal+JSON 构建器,它目前存在于我们的代码库中。它是同步的,因为它所做的只是创建一些相当小的对象文字,仅此而已,没有外部依赖项,当然也没有 IO 交互。
Is our approach a good one to take or not?
我们的方法是否适合?
回答by jevakallio
Let's say you have two functions, foo
and bar
, which are executing synchronously:
假设您有两个同步执行的函数foo
和bar
:
function foo() {
var returnValue = bar();
console.log(returnValue);
}
function bar() {
return "bar";
}
In order to make the API "asynchronous" is to change it to use callbacks:
为了使 API“异步”是将其更改为使用回调:
function foo() {
bar(function(returnValue) {
console.log(returnValue);
});
}
function bar(callback) {
callback("bar");
}
But the fact of the matter is, this code is still entirely synchronous. The callback is being executed on the same call stack, and no threading optimizations are being made, no scalability benefits are to be had.
但事实是,这段代码仍然是完全同步的。回调是在同一个调用堆栈上执行的,并且没有进行线程优化,也没有可扩展性优势。
It then becomes a question of code readablity and coding style. I personally find the typical var val = func();
type code more readable and readily understandable. The only drawback is, that if you one day would need to change the functionality of bar
so, that it would need to perform some I/O activity or call some other function which is asynchronous, you need to change the API of bar
as well.
然后它变成了代码可读性和编码风格的问题。我个人认为典型的var val = func();
类型代码更具可读性和易理解性。唯一的缺点是,如果有一天你需要更改bar
so的功能,它需要执行一些 I/O 活动或调用一些其他异步函数,你也需要更改 的 API bar
。
My personalpreference: use traditional, synchnous patterns when applicable. Always use asynchronous style when I/O is involved or when in doubt.
我的个人偏好:在适用时使用传统的同步模式。当涉及 I/O 或有疑问时,请始终使用异步样式。
回答by AndyD
Turning a synchronous function into an asynchronous one using process.nextTick() is an option, but one you should only use if your software is blocking for too long. Every time your synchronous function is running node can't do anything else as it's single threaded. This means that if your application is a server, it becomes unresponsive.
使用 process.nextTick() 将同步函数转换为异步函数是一种选择,但只有在您的软件阻塞太长时间时才应该使用。每次您的同步函数运行时,节点都不能做任何其他事情,因为它是单线程的。这意味着如果您的应用程序是服务器,它将变得无响应。
Before you split up any synchronous function, I would advise to first do some benchmarking and profiling so you can make an informed decision. Otherwise you run the risk of dong a premature optimisation
在拆分任何同步函数之前,我建议先进行一些基准测试和分析,以便您做出明智的决定。否则你会冒着过早优化的风险
See here for a good discussion https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil
Here's how you can make your function asyncronous, in the sense that you will allow node to do other things http://howtonode.org/understanding-process-next-tick
以下是如何使您的功能异步,从某种意义上说,您将允许节点做其他事情http://howtonode.org/understanding-process-next-tick
回答by freakish
I don't what's "Hal+Json builder", but here's what I think about NodeJS. You should write your code as asynchronous as possible, pushing it to it's limits. The simple reason is that asynchronous code trades performance for responsiveness, which is in most cases more important.
我不知道什么是“Hal+Json builder”,但这是我对 NodeJS 的看法。你应该尽可能异步地编写你的代码,把它推到极限。原因很简单,异步代码以性能换取响应能力,这在大多数情况下更为重要。
Of course if certain operations are really quick, then there is no need for asynchronous code. For example consider this code:
当然,如果某些操作真的很快,那么就不需要异步代码。例如考虑这个代码:
var arr = []; // assume array is nonempty
for (var i = 0, l = arr.length; i < l; i++) {
arr[ i ].doStuff( );
}
If arr
is small and doStuff
is a quick operation, then you should not bother in writing this code in asynchronous way. However if it takes some time, then you should consider writing it like that:
如果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( );
Now this code is truely asynchronous. It will take even more time for it to complete the job, but in the meantime it won't block entire server. We've traded performance for responsiveness.
现在这段代码是真正异步的。它需要更多的时间来完成这项工作,但同时它不会阻塞整个服务器。我们已经用性能换取了响应能力。
Conclusion:It depends on your situation! :)
结论:这取决于你的情况!:)