依赖Nodejs

依赖Nodejs

背景

前端历史演变中已经提到,Nodejs的爆发从2009年开始。Nodejs的出现,基于作者Ryan Dahl 对Web开发高性能的追求,要达到高性能,异步IO/事件驱动是基本原则。对比一些高级语言,最终选择Javascript作为开发语言,由于Javascript天生的事件驱动和单线程,奠定了Nodejs编写高性能Web服务轻而易举。

简单了解Nodejs

Node.js 是一个基于 Chrome V8 引擎JavaScript 运行环境。 
Node.js 使用了一个事件驱动非阻塞式 I/O 的模型,使其轻量又高效。 

以上是官方给出的解释,惯例我们还是抽取关键词理解。

Chrome V8 引擎介绍

V8 引擎是Chrome于2008年9月2日发布开源。V8使用C++开发,相比其它的JavaScript的引擎转换成字节码解释执行,V8将其编译成原生机器码IA-32x86-64ARM, or MIPS CPUs),并且使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript程序在V8引擎下的运行速度媲美二进制程序
Chrome浏览器在Webkit渲染引擎中使用v8引擎来提高浏览器的渲染性能。
依赖Nodejs
上图是webkit大致结构,红色部分是webkit的默认引擎,在谷歌系列产品中被替换为v8引擎;
Nodejs是站在“巨人的肩膀”上进行一系列的封装,它的高性能,离不开Chorme V8引擎。

JavaScript 运行环境

Javascript 是一个静态脚本语言,运行时必须要借助于引擎才能运行。
Javascript 运行环境一般分为两种:

  • 浏览器运行环境 ( 通常我们写的js代码要在浏览器中才能运行)
  • 非浏览器运行环境 (比如Nodejs,借助于V8引擎实现运行的环境)

事件驱动

我们在Javascript中注册个事件(回调函数)。但这个事件不是马上执行。只有等事件被触发的时候,才会去执行这个事件(回调函数)。这种形式就是事件驱动。

非阻塞 I/O 

阻塞:前一个程序未执行完就得一直等待。比如当你打电话问个问题时,那边说你等等我给你查查,这时候你电话仍然是挂起的,等待等待,直到拿到结果。 
非阻塞:前一个程序未执行完时可以挂起,继续执行其他程序,等到使用时再执行。比如当你打电话过去问一个问题,然后挂电话,等那边找到结果就打电话给你。查问题这段时间,你该干嘛就干嘛。
I/O: 磁盘的写入(in)磁盘的读取(out)。在程序执行过程中必然要进行很多I/O操作,读写文件、输入输出、请求响应等等。I/O操作时最费时,举个例子,你要读一个文件,整个线程都暂停下来,等待文件读完后继续执行。换言之,I/O操作阻塞了代码的执行,极大地降低了程序的效率。


在Nodejs里面单线程可以通过回调函数(事件驱动)来做异步操作,达到非阻塞I/O的效果。

安装Nodejs

  • 可以在官网自行选择安装包下载
  • MacOS用户建议使用brew安装
#安装
brew install -g node
#卸载
brew uninstall nodejs
  • 使用nvm安装管理Nodejs版本
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
# or
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
# 放入环境变量
source ~/.bash_profile
# 判断是否安装成功
nvm list
# 安装node
nvm install 6.14.4 # or 10.10.0, 8.9.1, etc
# 判断node安装成功
node -v
npm -v

Nodejs 的简单使用

模块化规范 CommonJs

前端模块化中已经对CommonJs做了介绍,并使用exports导出模块,require引入模块,实现了一个简单案例。

  • require:引入一个模块
  • exports: 导出模块内容
  • module: 模块本身

使用Nodejs创建服务

// index.js
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

运行 node index.js 会起一个去 127.0.0.1:3000 的服务,并在浏览器中输出Hello world
依赖Nodejs

了解基础API

path 模块提供用于处理文件路径和目录路径的实用工具。

// 引用
const path = require('path');
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// 返回: '/foo/bar/baz/asdf'

// path.resolve() 方法将路径或路径片段的序列解析为绝对路径
path.resolve('/foo/bar', './baz');
// 返回: '/foo/bar/baz'

fs文件系统模块,对文件和目录进行读写操作。

// 引用
const fs = require('fs');
// 读取文件
fs.readFile('./test.txt', function(err, data) {
    if (err) {
        throw err;
    }
    console.log(data);
});
// 写入文件
fs.writeFile('input.txt', '我是新写入的内容', function (err) {
   if (err) console.error(err);
   console.log('数据写入的数据');
 });
// 删除
fs.unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('已成功删除 /tmp/hello');
});
// 重命名
fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  console.log('重命名完成');
});

更多Api参考Nodejs Api 官网。

参考:
Chrome V8 引擎介绍
百度百科V8介绍
Nodejs官网指南

相关推荐