Node.js同步与asynchronous

我目前正在学习node.js,我看到2个同步和asycn程序(同一个)的例子。

我明白一个callback的概念,但我试图理解第二个(asynchronous)的例子的好处,因为它们似乎是两个正在做同样的事情,即使这种差异…

你能否详细说明为什么第二个例子会更好? 我会很乐意得到更广泛的解释,这将有助于我理解这个概念。

谢谢!!

第一个例子:

var fs = require('fs'); function calculateByteSize() { var totalBytes = 0, i, filenames, stats; filenames = fs.readdirSync("."); for (i = 0; i < filenames.length; i ++) { stats = fs.statSync("./" + filenames[i]); totalBytes += stats.size; } console.log(totalBytes); } calculateByteSize(); 

第二个例子:

 var fs = require('fs'); var count = 0, totalBytes = 0; function calculateByteSize() { fs.readdir(".", function (err, filenames) { var i; count = filenames.length; for (i = 0; i < filenames.length; i++) { fs.stat("./" + filenames[i], function (err, stats) { totalBytes += stats.size; count--; if (count === 0) { console.log(totalBytes); } }); } }); } calculateByteSize(); 

你的第一个例子是阻止I / O。 换句话说,在遍历每个文件之前,您需要等到readdir操作完成。 那么在移动到下一个文件之前,您需要阻止(等待)每个单独的同步统计操作。 calculateByteSize()调用之后,没有任何代码可以运行,直到所有操作完成。

另一方面,asynchronous(第二个)示例使用callback模式都是非阻塞的。 这里,只要fs.readdir被调用(但在callback运行之前calculateByteSize() ,执行就返回到calculateByteSize()调用之后。 一旦readdir任务完成,它会执行一个匿名函数的callback。 在这里它循环遍历每个文件,并再次对fs.stat进行非阻塞调用。

第二个更有利。 如果你可以假装对readdir或stat的调用的范围可以从250ms到750ms完成(这可能不是这种情况),那么你将等待串行调用你的同步操作。 但是,asynchronous操作不会导致您在每次调用之间等待。 换句话说,循环读取readdir文件,如果您正在同步执行,则需要等待每个stat操作完成。 如果您要asynchronous执行此操作,则无需等待每个fs.stat调用。

在第一个例子中,单线程的node.js进程在readdirSync的整个持续时间内都被阻塞,除了等待返回结果之外,其他任何事情都无法执行。 在第二个示例中,进程可以处理其他任务,并且当结果可用时,事件循环将把它返回到继续的callback。 所以你可以通过使用asynchronous代码来处理更高的总吞吐量 – 在第一个例子中等待readdir的时间可能是执行代码的时间的几千倍,所以你浪费了99.9%或更多的CPU时间。

在你的例子中,asynchronous编程的好处确实不是很明显。 但是,假设你的程序也需要做其他事情。 请记住,您的JavaScript代码是在单个线程中运行的,所以当您select同步实现时,程序无法执行其他任何操作,只能等待IO操作完成。 当您使用asynchronous编程时,您的程序可以在IO操作在后台运行时执行其他重要任务(在JavaScript线程之外)

你能否详细说明为什么第二个例子会更好? 我会很乐意得到更广泛的解释,这将有助于我理解这个概念。

这完全是关于networking服务器的并发性(因此名称为“节点”)。 如果这是在构build脚本中,则第二个同步示例将是“更好的”,这是更直接的。 给定一个磁盘,使其asynchronous可能没有多less实际的好处。

但是,在networking服务中,第一个同步版本将会阻止整个过程,并打败节点的主要devise原则。 随着并发客户数量的增加,性能会变慢。 然而,第二个asynchronous的例子,在等待相对较慢的文件系统返回结果的同时性能会相当好,它可以同时处理所有相对较快的CPU操作。 asynchronous版应该基本上能够使文件系统饱和,不pipe你的文件系统能传递多less,节点就能以这样的速度把它发给客户端。

很多好的答案在这里,但一定要阅读文档:

同步版本将阻止整个过程,直到完成 – 停止所有连接。

在文档中有一个很好的同步vsasynchronous概述: http : //nodejs.org/api/fs.html#fs_file_system