2014-02-06 34 views
0

在Node.js的,我可以做几乎所有的异步操作的方式有两种:为什么Node.js具有fs方法的异步和同步版本?

var file = fs.readFileSync('file.html') 

或...

var file 
fs.readFile('file.html', function (err, data) { 
    if (err) throw err 
    console.log(data) 
}) 

是异步一个自定义错误处理的唯一好处?或者真的有理由让文件读取操作非阻塞?

+1

当您处于阻止呼叫中时,无法运行其他代码。你不想那样。 – SLaks

+0

http://stackoverflow.com/questions/13858909/synchronous-vs-asynchronous-code-with-node-js – xhallix

+1

这是为了您的方便,所以你可以选择做什么,一般你应该选择异步方法来不阻止线程。 – adeneo

回答

3

异步调用允许分支执行链和通过该执行链传递结果。这具有许多优点。

其中之一,该程序可以同时执行两个或更多的调用,并在结果完成时处理结果,而不一定按照他们第一次调用的顺序。

例如,如果你有一个程序等待两个事件:

var file1; 
var file2; 

//Let's say this takes 2 seconds 
fs.readFile('bigfile1.jpg', function (err, data) { 
    if (err) throw err; 
    file1 = data; 
    console.log("FILE1 Done"); 
});  

//let's say this takes 1 second. 
fs.readFile('bigfile2.jpg', function (err, data) { 
    if (err) throw err; 
    file2 = data; 
    console.log("FILE2 Done"); 
}); 

console.log("DO SOMETHING ELSE"); 

在上述情况下,bigfile2.jpg将返回第一和事情会后只需要1秒被记录。所以你的输出时间表可能是这样的:

@0:00: DO SOMETHING ELSE 
@1:00: FILE2 Done 
@2:00: FILE1 Done 

注意上面的日志为“DO SOMETHING ELSE”已登录的时候了。并且File2仅在1秒后执行......并在2秒钟完成File1。一切都在内完成,总共2秒尽管callBack订单是不可预知的。

而同步做它,它看起来像:

file1 = fs.readFileSync('bigfile1.jpg'); 
console.log("FILE1 Done"); 
file2 = fs.readFileSync('bigfile2.jpg'); 
console.log("FILE2 Done"); 
console.log("DO SOMETHING ELSE"); 

和输出可能类似于:

@2:00: FILE1 Done 
@3:00: FILE2 Done 
@3:00 DO SOMETHING ELSE 

通知需要共3秒执行,但订单你是怎么称呼它的。

做这通常同步需要更长的时间,一切就会结束(尤其是对外部流程像文件系统读取,写入或数据库请求),因为你在等待一件事移动到下一个之前完成。有时你想要这个,但通常你不需要。虽然有时候同步编程会更容易,因为您可以按特定顺序(通常)可靠地执行操作。

异步执行文件系统方法但是,您的应用程序可以在不等待文件系统进程完成的情况下继续执行其他与文件系统无关的任务。因此,一般而言,您可以在系统等待异步操作完成时继续执行其他工作。这就是为什么您通常会使用异步方法(通常)来处理数据库查询,文件系统和通信请求的原因。他们基本上允许在等待其他(I/O和非系统)操作完成时完成其他工作。

当您进入更高级的异步方法链接时,您可以执行一些非常强大的功能,例如使用少量代码创建范围(使用闭包等)并创建响应者以应对某些事件循环。

对不起,很长的答案。有很多原因可以让你选择同步或不同步,但希望这可以帮助你决定哪种方法最适合你。

1

异步版本的好处是,您可以在等待IO完成时执行其他操作。

fs.readFile('file.html', function (err, data) { 
    if (err) throw err; 
    console.log(data); 
}); 

// Do a bunch more stuff here. 

// All this code will execute before the callback to readFile, 
// but the IO will be happening concurrently. :) 
+0

将其描述为比其他人“更好”,这会误导人们对已经令人困惑的话题。如果您的程序处理网络请求,则必须专门使用异步。两者都用于节点,但有一些非常特殊的情况,一个是正确的,另一个是不正确的,但几乎没有任何情况下,您可以选择一个来获得收益。 –

0

当您编写事件驱动代码时,您希望使用异步版本,其中快速响应请求至关重要。 Node的典型例子是编写一个Web服务器。比方说,你有一个用户发出请求,这样服务器必须执行一堆IO。如果此IO同步执行,则服务器将阻塞。它将不会回答任何其他请求,直到它完成这个请求。从用户的角度来看,性能看起来很糟糕。因此,在这种情况下,您希望使用异步版本的调用,以便Node可以继续处理请求。

IO调用的同步版本存在,因为节点未使用而只有用于编写事件驱动代码。例如,如果您正在编写一个实用程序来读取文件并对其进行修改,并将其作为批处理操作的一部分(如命令行工具)写回磁盘,则使用IO操作的同步版本可以使您的代码更容易跟随。

3

这些主要是因为节点本身需要它们在程序启动时从磁盘加载程序的模块。更广泛地说,当一个服务最初启动但在接受网络连接之前,通常会执行一系列同步设置IO。一旦程序准备就绪(已经加载了TLS证书,配置文件已被读取等),然后网络套接字被绑定,并且此时一切都是异步的。