Node.js 阻塞与非阻塞的实现

Node.js是一个异步非阻塞I/O的JavaScript运行环境。在Node.js中非阻塞I/O是其最主要的特征。异步、事件驱动、非阻塞I/O是Node.js存在的原因之一。理解Node.js的阻塞与非阻塞是非常重要的。

什么是阻塞与非阻塞

阻塞是指在某个操作执行过程中会阻碍后续代码的运行。非阻塞指在某个操作执行过程中不会阻碍后续代码的运行。

在I/O操作中,阻塞在读取或写入数据时会阻塞后续代码的运行,而非阻塞则不会。

阻塞I/O

Node.js中的阻塞I/O是指在执行I/O操作时,阻塞后续代码的运行。由于Node.js是单线程运行,当主线程遇到阻塞I/O操作时,它将会停滞在那里等待I/O操作执行完成返回,阻塞了代码的执行和服务器的响应。

下面是一个阻塞I/O的例子:

const fs = require('fs');
// 在执行完读文件的操作之后会继续执行后面的代码
const data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log('程序执行结束');

fs.readFileSync()是Node.js的同步I/O函数,它会阻塞代码的执行并等待文件读取完毕返回数据后再执行后面的代码。因此在读取文件的过程中,程序被阻塞住,直到文件读取完毕并返回数据后才会输出数据和"程序执行结束"。

非阻塞I/O

Node.js中的非阻塞I/O是指在执行I/O操作时,不会阻塞后续代码的运行。Node.js通过事件循环机制实现非阻塞I/O。

下面是一个非阻塞I/O的例子:

const fs = require('fs');
fs.readFile('input.txt', function (err, data) {
    if (err) {
        return console.error(err);
    }
    console.log(data.toString());
});
console.log('程序执行结束');

fs.readFile()是Node.js的异步I/O函数,它会将I/O操作加入到事件队列中,继续执行后续代码,等待I/O事件完成后会被扔到事件循环机制中执行回调函数。因此在读取文件的过程中,程序会继续执行后续代码,输出"程序执行结束",直到文件读取完毕后才会输出文件数据。

阻塞I/O与非阻塞I/O的对比

阻塞I/O会在I/O操作完成前阻碍后续代码的执行,而非阻塞I/O不会阻碍后续代码的执行,因此非阻塞I/O对于I/O密集型的场景非常有用。

Node.js采用一种事件循环的机制来处理I/O请求。在事件循环的每一个循环次数中,Node.js都会从事件队列中取出并处理一个事件。如果事件处理函数中触发了I/O请求,那么程序会将请求交给操作系统并继续往后执行,直到I/O操作完成并触发相应的回调函数。

Node.js中通过回调函数的方式解决了阻塞I/O带来的性能问题,使得Node.js在I/O密集型的场景中有非常优异的表现。

示例说明

示例1:文件夹遍历

下面是一个使用Node.js来遍历指定文件夹的例子,使用阻塞和非阻塞的方式分别实现:

  • 阻塞方式
const fs = require('fs');

function getFileList(path) {
    const fileArr = [];
    const fileList = fs.readdirSync(path);
    fileList.forEach(function(file) {
        fileArr.push(file);
    });
    return fileArr;
}

const list = getFileList('./');
console.log(list);
  • 非阻塞方式
const fs = require('fs');

function getFileList(path) {
    const fileArr = [];
    fs.readdir(path, function(err, fileList) {
        fileList.forEach(function(file) {
            fileArr.push(file);
        });
        console.log(fileArr);
    });
}

getFileList('./');

示例2:HTTP服务器

下面是一个使用Node.js实现的简单的HTTP服务器,使用阻塞和非阻塞的方式分别实现:

  • 阻塞方式
const http = require('http');
const fs = require('fs');

http.createServer(function (req, res) {
    const data = fs.readFileSync('index.html');
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end(data);
}).listen(8080);
console.log('服务器启动成功!请在浏览器中访问 http://localhost:8080');
  • 非阻塞方式
const http = require('http');
const fs = require('fs');

http.createServer(function (req, res) {
    fs.readFile('index.html', function(err, data) {
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end(data);
    });
}).listen(8080);
console.log('服务器启动成功!请在浏览器中访问 http://localhost:8080');

在执行这个简单的HTTP服务器时,使用非阻塞方式的服务器在文件读取的同时可以继续响应客户端请求,而使用阻塞方式的服务器必须等待文件读取完成后才能响应客户端请求,性能明显落后。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Node.js 阻塞与非阻塞的实现 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • node连接mysql数据库遇到的问题和解决方案

    当使用Node连接MySQL数据库时,可能会遇到以下问题: 1.无法连接到数据库2.查询时出现错误3.无法处理回调函数 接下来我将分享一些解决这些问题的方法: 问题1:无法连接到数据库 当使用Node连接MySQL数据库时,可能会遇到无法连接到数据库的问题。出现这种情况可能是由于以下原因: 1.数据库已关闭2.重复的连接3.防火墙阻止了连接 下面是一个示例,…

    node js 2023年6月8日
    00
  • nodejs入门教程五:连接数据库的方法分析

    那么我们来讲解一下“nodejs入门教程五:连接数据库的方法分析”的完整攻略。 场景描述 在使用Node.js进行数据开发或者Web应用开发时,连接数据库是非常关键的一步。而Node.js可以连接的主流数据库有MongoDB、MySQL、PostgreSQL、SQLite等,而本文的示例代码将以MySQL数据库为例,介绍如何在Node.js中连接MySQL数…

    node js 2023年6月8日
    00
  • el-checkbox-group 的v-model无法绑定对象数组的问题解决

    el-checkbox-group 是 Element UI 中常用的多选框组件,它可以通过 v-model 来实现和数据的双向绑定。但是,有时候我们需要将多个多选框的选项值绑定到一个对象数组中,此时使用 v-model 绑定会出现一些问题,具体表现为无法正确绑定选中的多选框值到对象数组中。以下是解决该问题的完整攻略。 问题描述 当我们将 el-checkb…

    node js 2023年6月8日
    00
  • Node.js包管理工具

    Node.js包管理工具(npm)是一个命令行工具,可用于安装、升级、移除和管理Node.js软件包。以下是使用npm来管理Node.js包的攻略: 安装npm npm已经随Node.js集成,因此如果您已经安装了Node.js,则npm也已经安装。可以通过下列命令验证npm是否已经安装: npm -v 搜索软件包 可以通过npm来搜索可用的软件包。使用下列…

    node js 2023年6月7日
    00
  • node.js中事件触发器events的使用方法实例分析

    我们就来详细讲解一下“node.js中事件触发器events的使用方法实例分析”。 什么是Events? Events是 Node.js 的内置模块,用于实现异步事件驱动的架构。在node.js中,很多函数都支持事件回调的方式进行使用,例如HTTP服务的request事件、file模块的readfile事件等。 Node.js 中的许多对象都会分发事件:一个…

    node js 2023年6月8日
    00
  • 关于Mac下安装nodejs、npm和cnpm的教程

    下面是关于Mac下安装nodejs、npm和cnpm的完整攻略: 安装nodejs 下载安装包 首先,我们需要从官网(https://nodejs.org/en/download/)下载适合Mac操作系统的nodejs安装包,一般我们选择稳定版本即可。 安装 下载安装包后,打开安装包进行安装。安装过程中,需要注意一些选项: 在安装程序中,把nodejs的可执…

    node js 2023年6月8日
    00
  • 深入解析koa之中间件流程控制

    以下就是“深入解析koa之中间件流程控制”的详细攻略: 什么是中间件 中间件指的是在请求到达目标处理程序之前,对请求进行一些预处理、中转、处理、过滤等操作的代码。可以把中间件看作是一个管道,请求流经这个管道,在管道中的每个中间件都有机会修改或处理请求并将其传递给下一个中间件,最终到达处理程序或返回响应数据给浏览器。 在 Koa 应用中,中间件使用 async…

    node js 2023年6月8日
    00
  • Express实现Session身份认证的示例代码

    下面我将详细讲解“Express实现Session身份认证的示例代码”的攻略过程。实现Session身份认证需要以下几个步骤: 步骤一:安装依赖 首先,我们需要安装express和express-session两个依赖: npm install express express-session 步骤二:配置session 配置session需要使用expres…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部