同步编程(Java)
如果您熟悉 Java 或 .Net 等同步编程(编写一件接一件的代码)。采取以下代码,
例如:
var fs = require('fs');
var content = fs.readFileSync('simpleserver1.js','utf-8');
console.log('File content: ');
console.log(content);
它将简单 Web 服务器的代码写到控制台。代码按顺序工作,在下一行之后执行每一行。直到前一行完成执行后才会执行下一行。
虽然效果不错,
如果这个例子中的文件非常大并且需要几分钟怎么办?
阅读?
如何在该代码或长时间执行其他操作
操作正在运行?
如果你在 java 中工作,这些问题就不会出现,因为你有很多线程可以为你工作(服务多个请求)
异步编程(Node.Js)
但是当您使用 Node 时,您只有一个线程,它服务于所有请求。
所以来了异步编程,在javascript(Node)中帮助你
要在其他长操作运行时执行操作,我们使用function callbacks。下面的代码展示了如何使用异步回调函数:
var fs = require('fs');
fs.readFile('simpleserver1.js','utf-8', function(err,data){
if (err) {
throw err;
}
console.log(“executed from the file finishes reading”);
});
//xyz operation
请注意,“从文件执行完成读取”这一行是在读取文件时执行的,因此允许我们在执行文件的主要读取的同时执行其他操作。
现在查看代码中的//xyz operation。当文件被读取时,服务器不会等待文件被完全读取。它将开始执行//xyz operation,并在文件准备就绪时返回fs.readFile( 中提供的回调函数。
这就是 Node 中异步编程的工作原理。
另外,如果你想比较 java 和 Node,你可以阅读这个Article
编辑:
node.Js 单线程是如何实现的
让我们来看一个场景,客户端请求服务器:
假设:
1) 有单个服务器进程,比如serverProcess,
2) 有 2 个客户端请求服务器,例如 clientA 和 clientB。
3) 现在,考虑 clientA,将需要一个文件操作(作为一个
如上所示,使用fs)。
这里发生了什么,
流程:
1)clientA请求serverProcess,服务器得到请求,然后
它开始执行文件操作。现在它等到文件
准备好读取(尚未调用回调)。
2)clientB请求serverProcess,现在服务器空闲了
现在,因为它不服务于clientA,所以它服务于clientB,在
同时,来自fs.read 的回调,通知服务器该文件
数据准备好了,可以对其进行操作了。
3) 现在服务器开始为“clientA”提供服务。
现在你看,只有一个 server 线程处理了两个客户端请求,对吧?
现在如果这是 JAVA 会发生什么,您将创建另一个服务器线程来服务
clientB,而
clientA 正在由第一个线程提供服务,并等待读取文件。所以这就是 Node 是单线程的,这意味着一个进程处理所有请求。
问题:
虽然调用了另一个从文件系统准备数据的进程,但如何说节点是单线程的:
看,I/O(files/database),本身就是一个不同的进程,这里有什么区别,
1) 节点不会等待一切准备就绪(如 java),它只会开始下一个工作(或服务其他请求),但无论发生什么,节点都不会创建不同的线程来服务其余的请求(除非明确完成//虽然不推荐)。
2) 而 java 会自己创建另一个线程来处理新请求。