切换版本:nvm
特点:异步 I/O、单线程、跨平台
比如去医院看病挂完号可以去干别的,等医生通知
单线程:Node.js 保持了 JS 在浏览器中单线程的特点(一个进程只开一个线程)
Node.js 虽然是单线程模型,但是其基于事件驱动、异步非阻塞模式,可以应用于高并发场景
优点:
- 不用处处在意状态同步问题,不会发生死锁。
- 没有线程上下文切换带来的性能开销
缺点(解决方案后边会讲):
- 无法利用多核CPU
- 错误会引起整个应用退出,健壮性不足
- 大量计算占用 CPU,导致无法继续执行
如何利用多核 CPU ?
模块化机制
何为模块化?
根据功能或者业务将一个大程序拆分成相互依赖的小文件,再用简单的方式拼接起来。
为什么要模块化?不模块化会产生什么问题?
- 所有 script 标签必须保证顺序正确,否则会依赖报错。
- 全局变量存在命名冲突,占用内存无法被回收
- IIFE(Immediately Invoked Functions Expressions)/namespace 会导致代码可读性低等诸多问题
Node.js 支持 CommonJS 模块规范,采用同步机制加载模块。
Node.js 读文件的速度很快,因为 Node.js 部署在服务端,不用像浏览器那样发网络请求。
// greeting.js
const preFix = 'Hello';
const sayHi = function () {
return `${preFix} world`;
};
module.exports = {
sayHi,
};
// exports.sayHi = sayHi;
// index.js
const { sayHi } = require('./greeting');
console.log(sayHi()); // Hello world
加载方式:
- 加载内置模块 require('fs')
- 加载 相对|绝对 路径的文件模块
require('./file.js')
require('/User/.../file.js')
-
加在 npm 包,require('lodash')
npm 包查找原则:当前目录 node_modules -> 父级目录的 node_modules -> 沿着路径向上递归,直到根目录下的 node_modules -> 找到之后会加载 package.json main 指向的文件,如果没有 package.json 则依次查找 index.js、index.json、index.node
require.cache 中缓存着加载过的模块,缓存的原因:同步加载
- 文件模块查找耗时,如果每次 require 都需要重新遍历查找,性能会比较差。
-
在实际开发中,模块可能包含副作用代码。
AMD 是 RequireJS 在推广过程中规范化产出,异步加载,推崇依赖前置。
CMD 时 SeaJS 在推广过程中规范化产出,异步加载,推崇就近依赖。
UMD(Universal Module Definition)规范,兼容 AMD 和 CommonJS 模式
-
CommonJS 模块输出的是一个值的拷贝;ESM 模块输出的是值的引用
- CommonJS 模块时运行时加载;ESM 模块是编译时输出(提前加在)
Web 应用开发
Koa——基于 Node.js 平台的下一代 Web 开发框架执行过程:
- 服务启动
- 实例化 application
- 注册中间件
- 创建服务、监听端口
- 接受/处理请求
- 获取请求 req、res 对象
- req -> request、res -> response 封装
- request & response -> context
- 执行中间件
- 输出设置到 ctx.body 上的内容
常用中间件
- koa-router:路由解析
- koa-body:request body 解析
- koa-logger: 日志记录
- koa-views:模版渲染
- koa2-cors:跨域处理
- koa-session:session 处理
- hoa-helmet:安全防护
Koa 中间件繁多,质量参差不齐,需要合理选择,高效组合。
基于 Koa 的前端框架:ThinkJS/Egg
他们做了什么?
- Koa 对象 response / request / context / application 等拓展
- Koa 常见中间件库
- 进程管理
- 脚手架
网友评论