Node.js 如何处理并发

Node.js 如何处理并发

Node.js是一个基于Chrome的V8引擎构建的开源跨平台运行环境。它被用于开发高度可扩展的后端和服务器端应用程序。

Node.js采用了单线程事件循环架构,并且具有异步性质。这是Node.js能够轻松处理多个并发请求的两个主要原因,也是开发此类应用程序的明显选择。

Node.js的工作原理

Node.js 如何处理并发

Node.js工作 异步地 换句话说,当操作系统有一个I/O密集型的请求时,它不会阻塞来自客户端的传入请求。相反,它会将这个I/O请求传递给内部的C++线程,并从事件队列中选择下一个任务。

注意: 内部的C++线程可能有一个,也可能没有,但这不是这里关注的问题。

事件队列只是一个按照接收顺序存储传入请求的队列。当事件循环可用时,它将这些请求传递给事件循环。对于每个I/O请求,事件循环会接收并将其传递给内部的C++线程进行处理,然后自己变得可用来处理其他请求。然后,它使用JavaScript的回调函数的概念来接收之前发送给内部C++线程进行处理的任务的响应,并将其传递给客户端。

让我们通过一个示例来理解这个过程:

示例1:传统Web架构

function func() {
    console.log("Hey I am Line number 1");
    setTimeout(function () {
        console.log("Hey I am Line number 2");
    }, 2000);
    console.log("Hey I am Line number 3");
}
console.log("Hey I am Line number 4");
 
func();
JavaScript

在这里,我们有4个console.log()语句,按照1到4的顺序排列。假设这是一个传统的基于架构的应用程序,输出会像这样。

输出:

Hey I am Line number 4
Hey I am Line number 1
Hey I am Line number 3
Hey I am Line number 2
JavaScript

解释: 在这里,“Hey I am Line number 4”会先执行,因为它在函数调用之前。然后调用函数。接下来会打印出“Hey I am Line number 1”,并将传递给setTimeout的回调函数添加到浏览器的宏任务队列中,分别打印出“Hey I am Line number 3”,然后当setTimeout的第二个参数指定的时间到达时,JS事件循环会从队列中取出回调函数并执行,从而打印出“Hey I am Line number 2” 。

示例2:Node.js应用程序

function func() {
    console.log("Hey I am Line number 1");
    setTimeout(function () {
        console.log("Hey I am Line number 2");
    }, 2000);
    console.log("Hey I am Line number 3");
}
console.log("Hey I am Line number 4");
func();
JavaScript

这里有4个console.log()语句的顺序是从1到4。假设这是一个单线程非阻塞的应用程序,输出结果将会是这样的。

输出结果:

Hey I am Line number 4
Hey I am Line number 1
Hey I am Line number 3
Hey I am Line number 2
JavaScript

解释: 这里,”Hey I am Line number 4″ 将首先执行,因为它在函数调用之前。然后调用函数。然后将打印 “Hey I am Line number 1″,应用程序将因为函数调用而进入2秒(2000ms)的超时。现在,当应用程序等待2秒时,它不会阻塞后续请求,而是会处理下一个请求,因此打印 “Hey I am Line number 3″。一旦超时结束,将会执行这几行,并将 “Hey I am Line number 2” 打印到控制台。

这样,事件循环永远不会被特定请求占用或阻塞。这就是为什么 Node.js 在处理多个用户请求方面比传统的 web 服务器具有竞争优势,即并发性。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册