nodejs技术摘要

一、认识nodejs

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境(引自百度百科)。
在这里插入图片描述
我们都知道,浏览器是客户端的JavaScript运行环境,相对的,nodejs就是服务端的JavaScript运行环境。

我们说nodejs是服务端的运行环境,并不意味着nodejs只能用于为web提供后台服务。nodejs实际上是让JavaScript可以运行于浏览器之外,并且为JavaScript提供了本地文件系统访问、数据库访问,以及作为web后台服务所必需的http等接口,使JavaScript真正成为一门可以用于web后端的编程语言。JavaScript在nodejs的环境下运行,就像Java在虚拟机环境下运行一样。

因此,说nodejs是一门编程语言,这显然是错误的。nodejs本身只是为JavaScript提供了一个可以不在浏览器下运行的环境。既然是运行环境,那么它必定包含能够解析这门语言的编译器或解释器,nodejs的作者选择了性能卓越的JavaScript引擎:V8(由C++编写,主要用于Chromium和Chrome)。

仅仅有V8还是不够的,因为它只能解析JavaScript本身,无法为其提供访问操作系统其他服务的编程接口。要让JavaScript能作为服务端语言,至少要为其提供访问文件系统、数据库等的能力,并且提供http服务,nodejs的作者Ryan Dahl以及技术社区为此使用C++开发了一系列的模块,如fs(文件系统模块)、http(http服务模块)、mysql(mysql数据库模块)、oracledb(Oracle模块)等,这里的fs和http模块是核心模块,内置于nodejs核心运行环境内,无需额外安装。有了这些模块,你可以用JavaScript访问与操作系统相关的更多底层服务。
在这里插入图片描述
所以说,客户端的JavaScript等于ECMAScript + DOM + BOM,而服务端的JavaScript等于ECMAScript + fs + mysql + oracledb + http + os(操作系统模块) + net(TCP模块) + …

有了这些模块的支持,JavaScript才算完全脱离了浏览器环境,具备了与操作系统交互的能力,因此它可以作为web后端语言使用。

既然在nodejs环境下,JavaScript已经可以与操作系统交互了,那它就不限于作为web后端语言了。此时的JavaScript还常用于编写工具,比如常见的webpack、vue-cli、create-react-app等,甚至可以用于编写桌面应用,如微软旗下著名的基于electron的开发者工具vscode。

二、nodejs基本概念简介

1. nodejs与npm

npm是nodejs“附赠”的包管理工具,当然它也是nodejs的作者推荐的包管理工具(nodejs现已交由npm的作者来维护)。当你安装完nodejs,npm也就安装完成了。

npm的主要作用是管理第三方包(如一个vue组件、一个react组件,或者打包工具webpack以及各种脚手架等,都称为一个包)。使用npm命令,你可以从npm服务器上下载别人上传的第三方包或命令行到本地使用,也可以上传自己的本地包供别人使用。

比如你想下载webpack,可以使用以下命令:

npm install webpack -g

install webpack表示要安装webpack。-g参数表示这个包要安装到nodejs的根目录下,这样可以作为全局包使用。想要卸载已安装的包,可以使用uninstall命令。

npm访问的默认服务器地址是https://registry.npmjs.org/,上传下载第三方包的目标服务器都是它。如果使用淘宝镜像cnpm,访问的是淘宝的服务器,一般来说,该服务器每10分钟与官方服务器同步一次。

2. nodejs交互式解释器(REPL)

不同于Java,JavaScript是一门脚本语言,它的执行不需要经过编译,因此可以一行一行地执行。基于这个特点,nodejs为JavaScript提供了一个交互式解释器,用于在命令行即时编写和执行JavaScript。

安装完nodejs后,打开命令行,输入node,敲击回车,即可进入交互式执行环境:
在这里插入图片描述
出现一个大于号,表示已经进入交互式环境,接下来你可以输入JavaScript语句,敲击回车即可执行:
在这里插入图片描述
如果需要连续输入多行代码,可以按shift + 回车,解释器会换行但暂不执行上一语句。

使用nodejs提供的交互式解释器,可以方便地编写并运行少量JavaScript代码。如果代码量稍大,可以将代码保存在一个js文件中,然后用node命令执行该js文件,效果与在交互式环境下连续输入这些代码是一致的。

3. nodejs异步编程

nodejs使用了一个事件驱动、非阻塞式 I/O 的模型。它的非阻塞I/O是借助事件循环实现的。

我们都知道,JavaScript是一门单线程语言。如果同步地执行所有的任务,诸如网络请求、数据库查询这样的操作将耗费大量的时间,导致程序性能极低。所以和在浏览器中一样,nodejs也采用事件循环机制,通过回调函数来解决这个问题(图片来自菜鸟教程)。
在这里插入图片描述
相比于客户端JavaScript,服务端JavaScript具有更大的优势。因为客户端浏览器类型不一,版本也有所差异,对JavaScript版本的支持性差异很大,给前端页面开发带来了很大的限制。但在服务端,nodejs版本由我们决定,所以我们可以更放心地使用高版本语法,比如Generator函数、async函数等,来实现异步编程。

此外,nodejs还提供了child_process模块,为JavaScript提供多进程支持。它比浏览器端的webworker更加强大,因为webworker只是一种多线程实现,各个线程之间不具备通信能力,而由child_process创建的进程是可以通信的。

4. 全局对象global

我们知道,在浏览器环境下,全局对象是window。而在nodejs环境下,全局对象是global。

同window一样,引用global的属性也可以省略global。global的常见属性包括:

  1. __filename:当前脚本的绝对路径,含文件名
  2. __dirname:当前脚本所在的路径,不含文件名
  3. setTimeout()、clearTimeout()、setInterval()、clearInetrval():用法与浏览器环境下一致
  4. console:控制台对象,用法与浏览器下类似。不过浏览器环境下的控制台由浏览器提供,而nodejs环境的控制台通常指shell终端(即命令行窗口)。
  5. process:nodejs进程状态对象。为process绑定事件监听,可以在nodejs的各个生命周期下执行操作。与nodejs交互的过程中,我们经常会访问这个对象。

三、nodejs的几个常用模块

nodejs有很多模块,这里我们只对其中几个最为常用的进行一些简介,以对nodejs有个大致的了解。

1. fs模块

fs模块是nodejs提供的文件系统模块,提供一组类似于UNIX系统的文件操作API。引入fs模块非常简单:

let fs = require("fs");

得到了fs模块后,我们就可以像下面这样读取文件系统的一个文件:

// 异步读取
fs.readFile('input.txt', function (err, data) {
   if (err) {
       return console.error(err);
   }
   console.log("异步读取: " + data.toString());
});

还可以以同步的方式来读取文件:

// 同步读取
var data = fs.readFileSync('input.txt');
console.log("同步读取: " + data.toString());

实际上在Chrome浏览器中,JavaScript也具备读取本地文件内容的能力,但是向文件系统中写入内容是严格禁止的,因为这会给客户端安全带来极大的安全隐患。而在nodejs环境下,由于是服务端,不存在这类安全问题,因此nodejs提供的fs模块允许向文件系统写入内容:

var fs = require("fs");

fs.writeFile('input.txt', '新内容', function(err) {
   if (err) {
       return console.error(err);
   }
   console.log("数据写入成功!");
});

这会向当前文件夹下的input.txt写入“新内容”这几个字符,如果该文件不存在,将先创建它再写入。

nodejs提供的文件系统操作接口使得它可以为各种脚手架、打包工具等提供支持。比如vue或者react的脚手架,实际上就是利用nodejs提供的fs模块,根据输入的参数,复制事先写好的模板文件到目标文件夹下。而打包工具,如webpack,则是对项目文件夹下的文件进行整合压缩和输出,也离不开nodejs提供的文件系统操作API。

2. web模块

web模块由若干子模块组成,如http模块、https模块、ws模块、net模块(提供TCP连接)、url模块等,为web服务提供支持。有了这些模块的支持,nodejs才能为JavaScript提供完整的服务端环境。此外,在nodejs环境下,JavaScript还可以实现一个简单的客户端。

我们以一个简单的例子来介绍web模块(例子来自菜鸟教程):

首先我们在当前文件夹下新增一个index.html作为服务端资源,它的内容很简单:
index.html

<!DOCTYPE html>
<html>
  <body>
    Hello World!
  </body>
</html>

然后在同级目录下新建server.js:
server.js

var http = require('http'); // http模块
var fs = require('fs');  // 文件系统模块
var url = require('url');  // url解析模块

// 创建服务器
http.createServer( function (request, response) {  
   // 解析请求,包括文件名
   var pathname = url.parse(request.url).pathname;
   
   // 输出请求的文件名
   console.log("Request for " + pathname + " received.");
   
   // 从文件系统中读取请求的文件内容
   fs.readFile(pathname.substr(1), function (err, data) {
      if (err) {
         console.log(err);
         // HTTP 状态码: 404 : NOT FOUND
         // Content Type: text/html
         response.writeHead(404, {'Content-Type': 'text/html'});
      }else{             
         // HTTP 状态码: 200 : OK
         // Content Type: text/html
         response.writeHead(200, {'Content-Type': 'text/html'});    
         
         // 响应文件内容
         response.write(data.toString());        
      }
      //  发送响应数据
      response.end();
   });   
}).listen(8080);
 
console.log('Server running at http://127.0.0.1:8080/');

然后创建一个客户端文件client.js:
client.js

var http = require('http');
 
// 用于请求的选项
var options = {
   host: 'localhost',
   port: '8080',
   path: '/index.html'  
};
 
// 处理响应的回调函数
var callback = function(response){
   // 不断更新数据
   var body = '';
   response.on('data', function(data) {
      body += data;
   });
   
   response.on('end', function() {
      // 数据接收完成
      console.log(body);
   });
}
// 向服务端发送请求
var req = http.request(options, callback);
req.end();

打开命令行,输入以下命令:
在这里插入图片描述
这样我们的服务就运行起来了,运行网址是http://127.0.0.1:8080(如果你在浏览器地址栏输入http://127.0.0.1:8080/index.html,就可以看到本地的index.html页面)。

再打开一个命令行,然后输入:
在这里插入图片描述
可以看到,即使没有浏览器,我们也可以通过nodejs提供的http模块,从http://127.0.0.1:8080这个网址下请求到index.html的内容。只是此时的html文件由于没有浏览器的解析,只是作为一串普通字符串返回的。基于这一点,你可以在nodejs环境下,用JavaScript写一个爬虫程序,主要过程就是不断请求网页,然后对取到的网页字符串进行分析。

不同于Java,nodejs自行封装了http服务,因此JavaScript运行在nodejs环境下时不需要其他的web容器(如Tomcat、Jetty等)。

3. 数据库模块

作为服务端环境,访问数据库是必不可少的。nodejs为各大数据库提供对应的模块,以使JavaScript可以访问这些数据库。常见的模块如MySQL数据库的mysql模块,Oracle数据库的oracledb模块、MongoDB的mongodb模块等。这些模块不是nodejs的核心模块,需要从npm下载安装。

下面我们以Oracle数据库连接来介绍nodejs的oracledb模块的简单用法(需要先安装oracledb:npm install oracledb):

var oracledb = require('oracledb');

const param = {
    user: xxx,
    password: xxx,
    connectString: xxx(数据库地址及实例)
};
const sql = "select * from USER where id=:1";
let userId = "123";  // 待查询的用户id

oracledb.getConnection(param, function(err, connection){
    if (err) {
        console.error(err.message);
        return;
    }
    console.log("数据库连接成功");
    // 数组的userId元素将替换sql语句中的:1
    connection.execute(sql, [userId], function(err, res){
        if (err) {
            console.error(err.message);
        }

        console.log(JSON.stringify(res.rows[0]);
    })
})

使用不同的数据库时,安装对应的模块即可。

总结

nodejs是JavaScript的服务端环境,它使得JavaScript不仅可以用于编写web后端,还可以用于编写各种工具、脚手架等。

nodejs用很多框架,如express、koa、eggjs等,在实际使用nodejs搭建web服务时,常常直接使用这些框架。nodejs的作者推荐使用中间件模式来开发web后台服务,每个中间件就是一个处理函数,对请求进行一步处理,类似于Java的过滤器。这样开发者就可以专注于业务逻辑的开发。

nodejs社区非常活跃,有大量可用的模块,框架也是数不胜数,这里只是nodejs初识篇,等以后在工作中深入使用后再进行更细致的了解。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值