Node.js初学
服务端层我们更多把 Node 定位为 BFF 层实现,BFF 是 Backend For Frontend 的缩写,翻译成用户体验适配层。
什么是Node.js
官网描述:
Node.js
是一个基于Chrome V8
引擎的javaScript
运行环境Node.js
使用了一个事件驱动、非阻塞I/O
的模型,使其轻量又高效
在
Node.js
里运行javaScript
跟在Chrome
里运行javaScript
有什么不同
Chrome
浏览器用的是同样的javaScript
引擎和模型- 区别
Node.js
没有浏览器API
,即documnet
、window
等- 加了许多
Node.js API
Chrome
里写javaScript
控制浏览器Node.js
让你用类似的方式,控制整个计算机
Node.js
可以用来做什么
- 搜索引擎优化 + 首屏速度优化 = 服务端渲染
- 服务端渲染 + 前后端同构 =
Node.js
可扩展性
-
大型应用需要给使用者自定义模块的能力
-
使用
Node.js
做复杂本地应用- 可以利用
JS
的灵活性提供外部扩展 js
庞大的开发者基数让他们的灵活性得到利用
- 可以利用
-
在已有网站的情况下需要新开发客户端应用
-
用
Node.js
客户端技术(electron
)实现,最大限度复用现有工程
BFF
层
- 对用户侧提供
HTTP
服务 - 使用后端
RPC
服务
Node
特有Api
console.log(__filename); //当前路径文件名字
console.log(__dirname); //当前路径文件夹名字
/*process是node的全局变量,不用require直接能访问。*/
console.log(process); //进程对象
console.log(process.argv)); //返回当前进程的所有命令行参数,是个数组,前2个元素是node命令路径和被执行的文件路径
//所以经常用到 process.argv.slice(2),或者命令行参数
<script></script>
- 脚本变多时,需要手动管理加载顺序
- 不同脚本之间逻辑调用,需要通过全局变量的方式
- 没有
html
怎么办?node
中就没有html
,所以Node.js
需要一个模块管理的机制,CommonJS
模块规范
CommonJs
模块规范
js
社区发起,在Node.js
上应用并推广- 后续也影响到了浏览器端
js
require('') 为引入
export.test = 'test1' 为导出
,导出和引入是同一个引用,在引入的文件中,也是可以将export
中的内容进行修改实践
我们有个
area.js
文件看看node的commonjs规范流程
- 暴露文件给node并会给下面js包装
var math = require('math'); exports.area = function (radius) { return Math.PI * radius * radius; };
变为
(function (exports, require, module, __filename, __dirname) { var math = require('math'); exports.area = function (radius) { return Math.PI * radius * radius; }; });
这样每个模块文件之间都进行了作用域隔离。包装后的代码会通过vm原生模块的
runInThisContext
方法执行(类似eval
,只是有明确的上下文,不污染全局),返回一个具体function对象。
最后将当前模块对象的exports属性、require方法、module(模块自身)以及在文件定位中得到的完整文件路径和文件目录作为参数传递给这个function执行,执行后模块的exports属性返回给了调用方,其他变量方法无法被调用。
npm
Node.js
的包管理工具- 包即大佬写的
Node.js
模块npm init
生成package.json
Node.js
内置模块
- 内置模块都在
Node.js
的lib
文件夹里面EventEmitter
- 观察者模式
addEventListener
removeEventListener
- 观察者模式 缺点(******)
- 关键在于“不知道被通知者存在”
- 以及“没有人听还能继续下去”
Node.js
的异步:非阻塞I/O
I/O
即Input / Output
,一个系统的输入和输出阻塞
I/O
和非阻塞I/O
的区别就在于系统接受输入再到输出期间,能不能接受其他输入理解非阻塞
I/O
的要点在于
- 确定一个进行
Input / Output
的系统- 思考在
I/O
过程中,能不能进行其他I/O
Node.js
的异步编程:callback
- 回调函数格式规范
error-first callback
Node-style callback
- 第一个参数是
error
,后面的参数才是结果
Promise
当前事件循环得不到的结果,但未来的事件循环会给到你结果
是一个状态机
pending
fulfilled / resolved
rejected
.then 和 .catch
resolved
状态得Promise
会回调后面得第一个.then
rejected
状态的Promise
会回调后面的第一个.catch
- 任何一个
rejected
状态且后面没有.catch
的Promise
,都会造成浏览器 /Node
环境的全局错误执行
then
和catch
会返回一个新的Promise
,该Promise
最终状态根据then
和catch
的回调函数的执行结果决定
- 如果回调函数最终是
throw
,该Promise
是rejected
状态- 如果是回调函数最终是
return
,该Promise
是resolved
状态- 但如果回调函数最终
return
了一个Promise
,该Promise
会和回调函数return
的Promise
状态保持一致
async / await
async function
是Promise
的语法糖封装- 异步编程的终极方案 - 以同步的方式写异步
await
关键字可以“暂停”async function
的执行await
关键字可以以同步的写法获取Promise
的执行结果try-catch
可以获取await
所得到的错误
HTTP
应用层协议
五层网络协议
- 1.物理层
- 2.数据链路曾
- 3.网络层
- 4.运输层
- 5.应用层
一个网页请求,包含俩次
HTTP
包交换
- 浏览器向
HTTP
服务器发送请求HTTP
包HTTP
服务器向浏览器返回HTTP
包
HTTP
服务要做什么事情
- 解析进来的
HTTP
请求报文- 返回对应的
HTTP
返回报文
express
:npm i express
- 核心功能
- 路由
request / response
简化
request
:pathname
、query
等response
:send()
、json()
、jsonp
等
Koa
- 核心功能:
- 比
express
更机制的request / response
简化
ctx.status = 200
ctx.body = 'hello world'
- 使用
async function
实现的中间件
- 有“暂停执行的能力”,在执行下一个中间件的时候,它能把前面的中间件**(暂停掉)**
- 在异步的情况下也符合洋葱模型
- 精简内核,所有额外功能都移到中间件里实现
Express vs Koa
express
门槛更低,Koa
更强大优雅express
封装更多东西,开发更快速,Koa
可定制型更高
RPC
调用
Remote Procedure Call
(远程过程调用)和
Ajax
有什么相同点
- 都是俩个计算机之间的网络通信
- 需要双方约定一个数据格式
和
Ajax
有什么不同点?
- 不一定使用
DNS
作为寻址服务,Ajax
是使用DNS
寻址- 应用层协议一般不使用
HTTP
- 基于
TCP
或UDP
协议寻址 / 负载均衡
Ajax
:使用DNS
进行寻址RPC
:使用特有服务进行寻址
TCP
通信方式
- 单工通信
- 半双工通信(轮番单工通信)
- 全双工通信
二进制协议
- 更小的数据包体积
- 更快的编解码速率
Node.js Buffer
编解码二进制数据包
protocol-buffers
Node.js
- 全双共的通信通道搭建
- 关键在于用用层协议需要有标记包号的字段
- 处理以下情况,需要有标记包长的字段
- 粘包
- 不完整包
- 错误处理
windows cmd命令行下创建删除文件和文件夹
- 创建文件夹
md <folderName> 或 mkdir <folderName>
- 删除文件夹
rd 或 rmdir命令
,rd /s /q [盘符:\][路径\]新目录名
- 因为rd只能删除空的文件夹,而如果其中有子文件或子文件夹的时候就会停下来,这时我们加上/s就可以直接删除,但是删除过程中会提示你是否确定删除,对于懒癌患者我们有添加了/q,即quiet,安静模式;
- 创建文件:
type nul>*.*;
,创建非空文件夹echo [fileContent]>*.*
- 删除文件
del *.*
,如del myfile.txt