Egg.js 是什么?
是一个 web 后端框架,用来处理接收前端请求、从数据存取数据并返回响应给前端。
有类似功能的其它框架:Django、Rails、Nest.js、Spring Boot。
设计原则
不像其它框架那样提供全家桶(例如数据库、模板引擎,甚至前端框架等),Egg 只提供了 web 框架的核心特性,其它的扩展功能都使用插件进行集成。所以,Egg 本身是轻量的,同时灵活的插件系统使得 Egg 又能根据具体的项目需求进行配置,既能保证框架本身的灵活性和可扩展性,又能充分适应各个开发团队的差异,使开发者形成自己团队的框架特色。
Egg 奉行 约定优于配置,这一点与 Rails 十分相似:约定 统一了团队每个成员的风格,使用相同的配置和风格进行开发,能够大大减少学习成本和提升开发效率。Egg 的 Loader 就是做这样一个事情:约定一些东西,然后从约定中加载模块和配置(例如在 app/controller 中查找控制器等);用户可以按照自己的需求覆盖默认的约定,比如我非要在 app/controllers 中查找控制器。
与社区框架的差异
Express 使用广泛,按时约定强度不够,导致写法多样,风格不统一。
Sails 同样使用 约定大于配置,但是它提供了全家桶,相对于 Egg 的插件模式,显得笨重一点。
特性
- 核心特性 + 插件 的模式可以用来定制团队的框架
- 插件机制使得框架的功能可以进行高度扩展
- 内置多进程管理
- 基于 Koa 的框架,性能有保证
- 稳定
- 渐进式开发:从简单到复杂的丝滑过渡
Egg.js 和 Koa
异步编程模型
用 Node.js 做 web 后端框架的一个特点就是,函数都是异步的。ECMA2015 中加入了 Promise,ECMA2017 中引入了 异步函数。
异步函数
async/await
是语法层面提供的一个语法糖,通过 await
来等待一个 Promise 被 resolve 或者 reject,用同步的方式来执行异步函数。
同步的方式区别于回调的方式,前者将异步函数嵌入代码块中顺序执行,后者将异步函数以回调的方式传入,这样的话如果回调的层数过多,就会引发回调地域。
下面是 async/await
实现的异步函数的同步写法:
const fn = async function() {
const user = await getUser();
const posts = await fetchPosts(user.id);
return { user, posts };
};
转化成回调嵌套可能是这个样子:
const fn = function() {
return new Promise((resolve, reject) => {
getUser().then(user => {
fetchPosts(user.id).then(posts => {
resolve({ user, posts })
}).catch(err => reject(err))
}).catch(err => reject(err))
})
}
我也不知道写对没有,总之挺复杂的。相对而言,async/await
就要简洁的多。
Koa
Koa 和 Express 是同一个团队搞出来的,所以风格十分相似。
它们的区别主要有:
Middleware
Koa 使用洋葱模型:
其特点是:请求从左边进入,依次执行中间件,然后再次反向执行中间件,所以每个中间件会被执行两次。
洋葱模型使得我们可以非常方便的处理后置逻辑,如果你想在中间件执行完成之后还想做点什么。
Context
在 Koa 和 Express 中,Request 和 Response 是两个基本对象。
此外 Koa 还多了一个 Context 对象,用来存储一次请求的相关上下文信息,当然也包含了 Request 和 Response 两个东西。
异常处理
通过同步方式书写异步代码的一个好处是可以同时捕获所有中间件抛出的异常,只需要将我们的自定义异常处理中间件放到所有中间件的最前面即可。
async function onerror(ctx, next) {
try {
await next()
} catch (err) {
ctx.app.emit('error', err)
ctx.body = 'server error'
ctx.status = err.status | 500
}
}
Egg 继承于 Koa
Egg 是对 Koa 的增强。
扩展
Koa 中定义了四个基本对象:application, context, request and response.
在 app/extend/{application,context,request,response}.js 文件中可以快速扩展四个基本对象的原型。
插件
Egg 的插件机制更加强大,插件可以是
- extend:将辅助工具添加到四个基本对象的原型上
- middleware:添加中间件对请求进行前置和后置处理
- config:配置各个环境下插件的默认参数
使用中间件时不应该去考虑插件在不同环境下的参数差异,中间件作为插件的一种,它应该专注于完成自己的功能,对环境特异性的考虑这种事情应该交给专门的配置插件去做。
Egg 和 Koa 的版本关系
管那么多作甚,直接用 Egg2 就行了。
评论区