首先,我是初学者,试图了解什么是Node.Js.我有两个问题。
第一个问题
从 这篇文章 菲利克斯说,“在同一时间只能有一个回调触发。在回调完成执行之前,所有其他回调都必须排队”。
然后,考虑以下代码(从nodejs官方网站复制)
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
如果同时收到两个客户端请求,则表示以下工作流程:
- 收到第一个http请求事件,收到第二个请求事件。
- 收到第一个事件后,第一个事件的回调函数正在执行。
- 同时,第二个事件的回调函数必须等待。
我对吗?如果我是对的,怎么样 Node.js的 控制是否在很短的时间内有数千个客户请求。
第二个问题
术语“事件循环”主要用于Node.js主题。我已经将“事件循环”理解为以下内容 http://www.wisegeek.com/what-is-an-event-loop.htm;
事件循环 - 或主循环,是程序中的构造
控制和调度初始事件后的事件。
最初的事件可以是任何事情,包括按下按钮
键盘或单击程序上的按钮(在Node.js中,我认为
初始事件将是http请求,db查询或I / O文件访问)。
这称为循环,不是因为事件圈出而发生
不断,但因为循环准备一个事件,检查
事件,调度事件并重新重复该过程。
我有关于第二段的冲突,特别是“重复这个过程“我接受了上述内容 http.createServer 上面的问题代码绝对是“事件循环”,因为它反复监听http请求事件。
但我不知道如何识别以下代码,无论是事件驱动还是事件循环。除了在db查询完成后触发的回调函数之外,它不会重复任何操作。
database.query("SELECT * FROM table", function(rows) {
var result = rows;
});
请让我听听你的意见和答案。
回答一个,你的逻辑是正确的:第二个事件将等待。并且将在其排队的回调时间到来时执行。
同样,请记住技术世界中没有“同时”这样的东西。一切都有非常具体的地点和时间。
node.js管理数千个连接的方式是,在有一些数据库调用阻塞逻辑或者正在处理另一个IO操作(例如流)时,不需要保持线程空闲。它可以“提供”第一个请求,可能会创建更多回调,然后继续进行其他操作。
因为没有办法阻止执行(除了废话(真实)和类似),它在整个应用程序逻辑中传播实际资源变得非常有效。
线程 - 价格昂贵,线程的服务器容量与可用内存直接相关。因此,大多数经典Web应用程序都会受到影响,因为在数据库查询块正在进行或类似的情况下,RAM用于简单空闲的线程。在节点中,不是一个案例。
但是,它允许创建多个线程(作为child_process) cluster
,这扩大了更多的可能性。
答案二。没有你想到的“循环”这样的东西。幕后没有循环可以检查是否有连接或接收到任何数据等等。现在它也是由Async方法处理的。
因此从应用程序的角度来看,没有“主循环”,从开发人员的角度来看,一切都是事件驱动的(不是事件循环)。
如果有 http.createServer
,您将回调绑定为对请求的响应。所有套接字操作和IO内容都将在幕后发生,以及HTTP握手,解析标头,查询,参数等。一旦它在幕后发生并且工作完成,它将保留数据并将回调推送到具有一些数据的事件循环。一旦事件循环生效并且将到来它将在node.js应用程序上下文中执行您的回调与来自幕后的数据。
有了数据库请求 - 同样的故事。它不准备并询问内容(可能会再次执行异步),然后在数据库响应并且将为应用程序上下文准备数据时进行回调。
说实话,node.js所需要的只是理解概念,而不是事件的实现。
最好的方法 - 实验。
回答一个,你的逻辑是正确的:第二个事件将等待。并且将在其排队的回调时间到来时执行。
同样,请记住技术世界中没有“同时”这样的东西。一切都有非常具体的地点和时间。
node.js管理数千个连接的方式是,在有一些数据库调用阻塞逻辑或者正在处理另一个IO操作(例如流)时,不需要保持线程空闲。它可以“提供”第一个请求,可能会创建更多回调,然后继续进行其他操作。
因为没有办法阻止执行(除了废话(真实)和类似),它在整个应用程序逻辑中传播实际资源变得非常有效。
线程 - 价格昂贵,线程的服务器容量与可用内存直接相关。因此,大多数经典Web应用程序都会受到影响,因为在数据库查询块正在进行或类似的情况下,RAM用于简单空闲的线程。在节点中,不是一个案例。
但是,它允许创建多个线程(作为child_process) cluster
,这扩大了更多的可能性。
答案二。没有你想到的“循环”这样的东西。幕后没有循环可以检查是否有连接或接收到任何数据等等。现在它也是由Async方法处理的。
因此从应用程序的角度来看,没有“主循环”,从开发人员的角度来看,一切都是事件驱动的(不是事件循环)。
如果有 http.createServer
,您将回调绑定为对请求的响应。所有套接字操作和IO内容都将在幕后发生,以及HTTP握手,解析标头,查询,参数等。一旦它在幕后发生并且工作完成,它将保留数据并将回调推送到具有一些数据的事件循环。一旦事件循环生效并且将到来它将在node.js应用程序上下文中执行您的回调与来自幕后的数据。
有了数据库请求 - 同样的故事。它不准备并询问内容(可能会再次执行异步),然后在数据库响应并且将为应用程序上下文准备数据时进行回调。
说实话,node.js所需要的只是理解概念,而不是事件的实现。
最好的方法 - 实验。
1) 你是对的。
它的工作原理是因为您对节点所做的一切主要是I / O绑定。
当一个新请求(事件)进入时,它被放入队列中。在初始化时,Node分配一个ThreadPool,负责为I / O绑定处理产生线程,如网络/套接字调用,数据库等(这是非阻塞的)。
现在,您的“回调”(或事件处理程序)非常快,因为您正在执行的大多数操作很可能是CRUD和I / O操作,而不是CPU密集型操作。
因此,这些回调让人感觉它们是并行处理的,但它们实际上并非如此,因为实际的并行工作是通过ThreadPool(具有多线程)完成的,而回调本身只是接收结果从这些线程,以便处理可以继续并将响应发送回客户端。
您可以轻松验证这一点:如果您的回调是 重 CPU任务,你可以确定你不会每秒处理数千个请求,并且与多线程系统相比,它可以非常糟糕地缩小。
2) 你是对的。
不幸的是,由于所有这些抽象,你必须潜水,以了解背景中发生了什么。但是,是的,有一个循环。
特别是,Nodejs是用。实现的 libuv。
有意思 读。
但我不知道如何识别以下代码,无论是事件驱动还是事件循环。除了在db查询完成后触发的回调函数之外,它不会重复任何操作。
事件驱动是您在存在事件循环时通常使用的术语,它表示由诸如点击按钮,数据到达等事件驱动的应用程序。通常,您将回调与此类事件相关联。