koa2与nodejs实战

923 阅读11分钟

Nodejs的特点和应用场景

nodejs使用了事件驱动、非阻塞式I/O 模型,轻量又高效。

事件驱动是一种处理数据的方式,这种方式同传统的数据处理方式CRUD (增加、读 取、更新、删除)截然不同。在CRUD 模式中只保存数据的当前状态,因此所有的后续变 更都会直接在数据本体上进行处理。这样做的弊端主要有:

  • CRUD 会直接在数据存储区进行操作,会降低响应速度和性能水平,对进程的开销过大也会限制项目的规模和可扩展性。
  • 在存在大量并发用户的协作域中,对于同一数据主体的操作很可能会引起冲突。
  • 在没有额外监听措施的情况下,任何节点能够获得的只有当前的状态快照,历史数据会丢失。

事件驱动( Event Sourcing )定义了一种由事件驱动的数据处理方式,应用发送的所有 事件都会被载入附加存储区,每一个事件都代表了一系列的数据变更。被保留下来的事件 会作为操作历史留存下来,与此同时事件流会被不间断地同步到客户端供其使用,例如更 新整体的物化视图( Materialized View ),把事件流提供给外部系统,或者通过重演与特定 物体有关的历史事件来确定它的当前状态等。以在虚拟商城中添加物品到购物车的过程为 例,事件驱动的数据处理过程如图所示。

image.png

对比CRUD ,事件驱动的优势是显而易见的:

  • 己经发生的事件是不可更改的,并且只在附加区域中存储而不影响主线程,因此对事件进行处理的操作完全可以在后台进行而不影响到客户端的UI 和内容展示。这对性能优化和提升应用的可扩展性来说大大有利。
  • 不同用户对同一个对象的同时操作不会产生冲突,因为这种数据处理方式避免了对数据本身的直接更改。
  • 附加区域中存储的事件流实际上提供了一个监听机制,使开发者能够通过重演历史事件的方式来获取当前状态,进而有助于系统的测试和漏洞修复。

更多关于事件驱动和物化视图的内容请参考Microso企Azure 的官方文档,地址如下: docs.microsoft.com/en-us/azure…, docs.microsoft.com/en-us/azure…

事件驱动的异步I/O 模型使得Node.js 非常适合用来处理I/O 密集型应用,但也不限于 此,例如Web 聊天室( Socket.io )、Web 博客( Hexo ) 、Web 论坛( Node Club )、前端 模块管理平台( Bower.js )、浏览器环境工具( Browserif沪、命令行工具( Commander) 等。流行的Node.js 应用框架有Express 、Koa 、Meteor 等。

提示: Node.js 能够运行在Linux ~ macOS 、Microsoft Windows 、UNIX 等平台上,并且可以用能够被编译为JavaScript 的任何语言(包括CoffeeScript 和Typescript 等)进行编写。使用Nod巳. 进行开发的过程其实就是使用JavaScript 结合一系列处理核心功能的模块来创建如Web 服务器、通信等工具的过程。其中,这些模块承担着诸如读取与存入文件、通信、双向数据交换、加密解密等功能,且开放API ( Application Programming Interface ,应用程序编程接口)供开发者使用。

koa中间件

中间件是Koa 中一个非常重要的概念。Koa 应用程序其实就是一个包含一组中间件函数的对象,而且有了async/await 这种高级语法糖,使中间件写起来更加简单。

常用的koa中间件

  1. koa-bodyparser 中间件

  2. koa-router

  3. koa-static

  4. koa-views

路由

命名路由

//设置此路由的名称为user
router.get('user','/users/:id',function(ctx, next) {
 II
));

//通过调用路由的名称user, 生成路由 == '/users/3'
router.url('user', 3);

//通过调用路由的名称user ,生成路由 == '/users/3'
router.url('user', {id: 3});

router.use(function(ctx , next){
 //重定向到路由名称为sign - in 的页面
 ctx.redirect(ctx.router.url('sign-in'));
))

路由前缀

通过prefix 参数,可以为一组路由添加统一的前缀。和嵌套路由类似,这样做有利于管理路由及简化路由的写法,代码如下:

let router = new Router({
 prefix: '/users'
});

//匹配路由'/users'
router.get('/', ...);

//匹配路由'/users/:id'
router.get('/:id', ...);

URL参数

router.get('/:categoryl:title', function(ctx, next) {
 //响应请求 '/programming/how-to-koa'
 console.log(ctx.params);
 //参数解析=> {category: 'programming', title:'how-to-koa'}
});

模板引擎

模板引擎是Web 应用中用来生成动态HTML 的工具,负责将数据模型与HTML 模板结合(模板渲染),生成最终的HTML 。编写HT ML 模板的语法被称为模板语法,模板语法的表达能力和可扩展性决定了模板引擎的易用性。

常见的模板引擎有哪些

目前,可以在Node.js 中应用且比较成熟的模板引擎有很多,例如EJS 、Jade(现己改名为Pug ) 、Handlebars 、Nunjucks 、Swig 等。在项目中使用这些模板引擎,可以让项目代码脉络更加清晰,结构更加合理,也可以让项目的维护变得更加简单。然而因为众多模板引擎的特点和适用场景各不相同,因此并不存在适合所有项目的最完美的那一个。只有更多地了解模板的特点及应用场景,充分认识不同模板引擎的优劣,才可以正确地在各模板 中进行选择。

  1. EJS “ E ”代表“ effective ”,即“高效” 。EJS 是一个简单、高效且支持Express 视图系统的模板语言,通过数据和模板,加上简单的模板标签,能够快速编译并生成HTML 标记文本。不足之处是不支持模板导入功能。可以说EJS 是一个JavaScript 库,可以同时运行在客户端和服务器端。在客户端安装时直接引入文件即可,在服务器端可以用NPM 包安装,代码如下:
<div class=”entry">
  <% if(title) { %>
</div>
  1. Jade Jade 曾一度成为Express 的默认模板引擎,它致力于生成良构的HTML ,提供了极其简洁的E mmet 风格的模板语法。Jade 不兼容H TML ,相对于EJS 来说, 学习成本略高。Jade在设计风格上借鉴了Ha ml 的很多地方,所以语法上和Ha ml 比较相近。另外, Jade 也支持空格。

在Jade 里,每一行开头的任何文本都被默认解释成HTML 标签,在书写时只需要写开 始标签即可,代码如下:

  1. Swig

  2. Nunjucks unjucks 是Mozilla 开发的一个纯JavaScript 编写的模板引擎。如果读者使用过Python的模板引擎Jinja2,那么使用Nu可ucks 就会非常简单。因为Nunjucks 就是用JavaScript 重新实现了Ji叼ia2 ,两者的语法几乎一模一样。先看一下如何在Node.js 项目中应用Nunjucks 。文档示例中介绍了在Express 中的启用方式,代码如下:

数据库

什么是数据库

简单来说,数据库就是存储、管理数据的仓库,它提供了对数据的检索、存储、多用 户共享访问的能力,并且设法使数据的冗余度尽可能小。一般会为了管理数据库设计软件 非实品,仅供非商业用途或交流学习使用 前 Koa2 与f\lode . js 开发实战 系统,该系统被称为数据库管理系统。

数据库的特点

  • 数据共享。数据库中的数据可以同时被多人查询和写入。 减少数据冗余度。与文件系统相比,数据库实现了数据共享,从而避免了文件的复 制,降低了数据冗余度。
  • 数据独立。数据库中的数据和业务是独立的。
  • 数据一致性和可维护性。数据库中的数据应当保持一致,以防止数据丢失和越权使 用。在同一周期内,既能允许对数据实现多路存取,也能防止用户之间的数据操作 相互影响。
  • 故障恢复。可以及时发现故障和修复故障,从而防止数据被损坏。

数据库一般采用索引来提升查询效率。可以通过这样的模型来说明索引的作用:将一 个小区当作数据库,那么,楼号是数据表,房间是数据记录。如何快速查询出指定的房间 号呢?在现实世界中,采用房间地址(小区+楼号+房间号)可以快速定位房间。在数据库 中,也采用了相似的方式:通过采用合适的索引,将数据排序;在查询时,通过索引算法, 快速查出数据。

为了实现数据的一致性,数据库操作是基于事务的。通过事务,也就是一组有序的数 据库操作指令,进行“捆绑”执行,要么全部执行,要么全部不执行,从而保证了数据的 一致性和完整性。在多个事务同时需要被执行时,通过控制多个并行事务轮流执行,避免 多个并发事务同时执行。

数据库按照存储的数据模型,分为关系型数据库和非关系型数据库。

  • 关系型数据库:把复杂的数据结构归结为简单的二维表格形式,表格之间的数据关 系通过主外键关系来维系。这样的数据库就称为关系型数据库。在应用开发中,大 多数业务都可以抽象为二维表格,可以采用关系型数据库存储数据。

  • 非关系型数据库: 和关系型数据库对应,随着应用开发的发展,人们发现关系型数 据库能很好地处理表格型数据,但在某些业务场景下,需要存储的数据并不能简单 地抽象为二维表格,存储的数据字段并不能确定,在这种场景下使用关系型数据库 不利于数据处理,于是直接处理对象的数据库就应运而生了。另外,在应用开发中, 有些应用存储的数据结构简单,并不需要采用关系型数据库,开发者也倾向于选择 非关系型数据库存储这类数据。

Koa 中应用Mysql 数据库

Koa 中应用MongoDB 数据库

MongoDB 是由C++编写的基于分布式文件存储的开源数据库,在No d e.js 应用中使用 广泛。可以直接在MongoDB 宫网下载安装文件。在下载页面中提供了几个版本,一般选择 免费的社区版下载。

1 . 在macOS 系统下安装 在macOS 系统中,下载安装文件之后,双击己下载的压缩包,解压后得到MongoDB的程序文件。首先将程序文件移动到指定位置,如/usr/local/mongodb 。然后修改环境变量,将MongoDB 的bin 目录加入PATH 环境变量中。可以编辑用户目录下的re 文件(~/.bashrc ) 来修改它, 在文件中增加一行代码修改PATH 环境变量, 代码如下:

export PATH=/usr/local/mongodb/bin:$PATH

至此, MongoDB 己经安装完成,接下来需要启动MongoDB 服务。首先建立数据目录,创建命令如下:

mkdir -p /data/db

在启动MongoDB 服务前, 需要首先确保运行MongoDB 的用户具备前面创建的数据目 录的读写权限。此时可以启动MongoDB 服务, 启动命令如下:

mongod --dbpath /data/db
  1. 在Windows 系统下安装

image.png 对于特定的数据类型,有其特有的约束。例如Number 类型, 可以指定Max 、Min 等约束。读者可以通过官方文档查看这些特定的约束。为了提高查询效率, 一般会对查询的字段配置索引来优化查询, 通过index 属性来开启, 代码如下:

const categorySchema = new mongoose.Schema ({
 name: {
     type : String ,
     index : true, //对该字段启用索引
     unique: true //该字段的约束为唯一
 ) ,
))

提示:和关系型数据库中的索引一样,在写入数据时, 需要维护索引信息,这会降低数据写入效率,因此不能滥用索引。

Koa 中应用Redis 数据库