初步了解nodejs
一、nodejs的特点
- 它是一个 javascript 的运行环境
- 依赖于 V8 引擎进行代码解析
- 事件驱动
- 非阻塞 I/O
- 轻量、可伸缩
node.js 是一个基于 Chrome V8 引擎的 JavaScirpt 运行环境。它最大的优势就是借助JavaScript天生的事件驱动机制加上V8高性能引擎,使编写高性能web更加轻松
二、基本使用
require()引入模块,返回一个模块对象;
代码如下(示例):
const readline = require('readline-sync');
//文件模块
module.exports()或者exports() 导出一个对象
代码如下(示例):
// index.js
// 导出模块
module.exports.name = 'nihao;
module.exports.sayHello = function(){
console.log('Hello');
}
// index2.js
// 导入模块
let obj = require('./index.js');
console.log(obj.name); // nihao
obj.sayHello(); // Hello
- 注意:exports是指向module.exports,最终导出的module.exports
npm
- Node Package manager,“node 包管理器”,上面有各种各样的包
npm都是一些简单的命令,详情见官网:
https://www.npmjs.cn/getting-started/installing-node/ - 默认情况下,我们在拉包的时候,是从 npm 官网上面去拉包,但是在国内,有一个很尴尬的问题,速度很慢,甚至拉包拉不下。国内的淘宝团队在国内搭建了一个镜像服务器,因为服务器在国内,所以速度很快。
代码如下(示例):
//修改镜像
npm config set registry https://registry.npm.taobao.org
2.nodejs两个最大的特点 异步无阻塞和事件驱动
异步无阻塞
- 在 node中,由于采用异步的方式来处理阻塞代码,所以在回到函数中,采用错误优先原则。
代码如下(示例):
const fs = require('fs');
console.log('开始写入文件');
fs.readFile('./test.txt',function(err,data){
if(err) throw err;
console.log(data.toString());
})
console.log('结束写入文件');
事件驱动
- EventEmitter,事件驱动模式
- EventEmitter 是 node 里面为我们提供的一个模块,允许我们自定义事件。
const EventEmitter = require('events').EventEmitter;
const event = new EventEmitter();
// 手动定义一个事件
event.on('event',function(){
console.log('你触发了这个事件');
})
// 手动来触发
setTimeout(function(){
event.emit('event');
},2000);
nodejs 系统架构
nodejs 的架构如下图:
该图展示了整个 Node 的运行原理,从左到右,从上到下,整个 Node 被分为了 4 层,分别是应用层、V8 引擎层、Node API层和LIBUV层。
应用层:即 JavaScript 交互层,常见的就是 Node 的模块,比如http
,fs
。
V8 引擎层:即利用 V8 引擎来解析 JavaScript 语法,进而和下层 API 交互。
NodeAPI 层:为上层模块提供系统调用,一般是由 C 语言来实现,和操作系统进行交互。
LIBUV 层:是跨平台的底层封装,实现了事件循环、文件操作等,是 Node 实现异步的核心。
无论是 Linux 平台还是 Windows 平台,Node 内部都是通过线程池来完成异步 I/O 操作的,而 LIBUV 针对不同平台的差异性实现了统一调用。
- 当我们使用 Node.js 的时候,会在 JavaScript 中触发一些命令调用方法,这些方法会被包装成一个对象,放入线程池,然后前面的方法就返回了,继续执行下面的 JavaScript 代码。
线程池中采用多线程的方式执行,执行完的对象放入事件循环队列。
事件循环队列采用类似 while(true) 这种循环的方式,不断的查看是否有事件,并且读取是否包含回调,由于前面回调函数被包装到对象中,这里直接调用执行就可以了。
因此,Node.js 的单线程仅仅是指 JavaScript 运行在单线程中,而并非整个 Node.js 运行环境是单线程。